Example #1
0
        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);
        }
Example #2
0
        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);
            }
        }
Example #3
0
        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());
            }
        }
Example #4
0
        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!");
        }
Example #5
0
        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);
        }
Example #6
0
        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);
        }
Example #7
0
        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);
        }
Example #8
0
        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" }
            });
        }
Example #9
0
        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());
        }
Example #10
0
        public void Update()
        {
            while (SteamNetworking.IsP2PPacketAvailable(0))
            {
                P2Packet?packet = SteamNetworking.ReadP2PPacket(0);

                if (packet.HasValue)
                {
                    P2PMessage msg = new P2PMessage(packet.Value.Data);

                    MessageType type = (MessageType)msg.ReadByte();

                    switch (type)
                    {
                    case MessageType.Join:
                    {
                        if (msg.ReadByte() != JobSimulatorMultiplayer.PROTOCOL_VERSION)
                        {
                            // Somebody tried to join with an incompatible verison
                            P2PMessage m2 = new P2PMessage();
                            m2.WriteByte((byte)MessageType.JoinRejected);
                            SteamNetworking.SendP2PPacket(packet.Value.SteamId, m2.GetBytes(), -1, 0, P2PSend.Reliable);
                            SteamNetworking.CloseP2PSessionWithUser(packet.Value.SteamId);
                        }
                        else
                        {
                            MelonModLogger.Log("Player joined with SteamID: " + packet.Value.SteamId);
                            players.Add(packet.Value.SteamId);
                            MelonModLogger.Log("Player count: " + players.Count);
                            byte newPlayerId = smallIdCounter;
                            smallPlayerIds.Add(packet.Value.SteamId, newPlayerId);
                            largePlayerIds.Add(newPlayerId, packet.Value.SteamId);
                            smallIdCounter++;

                            string name = msg.ReadUnicodeString();
                            MelonModLogger.Log("Name: " + name);

                            foreach (var smallId in playerNames.Keys)
                            {
                                ClientJoinMessage cjm = new ClientJoinMessage
                                {
                                    playerId = smallId,
                                    name     = playerNames[smallId],
                                    steamId  = largePlayerIds[smallId]
                                };
                                SteamNetworking.SendP2PPacket(packet.Value.SteamId, cjm.MakeMsg().GetBytes(), -1, 0, P2PSend.Reliable);
                            }

                            ClientJoinMessage cjm2 = new ClientJoinMessage
                            {
                                playerId = 0,
                                name     = SteamClient.Name,
                                steamId  = SteamClient.SteamId
                            };
                            SteamNetworking.SendP2PPacket(packet.Value.SteamId, cjm2.MakeMsg().GetBytes(), -1, 0, P2PSend.Reliable);

                            playerNames.Add(newPlayerId, name);

                            ClientJoinMessage cjm3 = new ClientJoinMessage
                            {
                                playerId = newPlayerId,
                                name     = name,
                                steamId  = packet.Value.SteamId
                            };
                            ServerSendToAllExcept(cjm3, P2PSend.Reliable, packet.Value.SteamId);

                            playerObjects.Add(newPlayerId, new PlayerRep(name, packet.Value.SteamId));

                            RichPresence.SetActivity(
                                new Activity()
                                {
                                    State   = "Hosting a server",
                                    Assets  = { LargeImage = "jobsim" },
                                    Secrets = new ActivitySecrets()
                                    {
                                        Join = SteamClient.SteamId.ToString()
                                    },
                                    Party = new ActivityParty()
                                    {
                                        Id   = partyId,
                                        Size = new PartySize()
                                        {
                                            CurrentSize = players.Count + 1,
                                            MaxSize     = JobSimulatorMultiplayer.MAX_PLAYERS
                                        }
                                    }
                                });

                            SceneTransitionMessage stm = new SceneTransitionMessage()
                            {
                                sceneName = SceneManager.GetActiveScene().name
                            };
                            SendToId(stm, P2PSend.Reliable, packet.Value.SteamId);

                            SetPartyIdMessage spid = new SetPartyIdMessage()
                            {
                                partyId = partyId
                            };
                            SendToId(spid, P2PSend.Reliable, packet.Value.SteamId);
                        }
                        break;
                    }

                    case MessageType.Disconnect:
                    {
                        MelonModLogger.Log("Player left with SteamID: " + packet.Value.SteamId);
                        byte smallId = smallPlayerIds[packet.Value.SteamId];

                        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 == packet.Value.SteamId);
                        smallPlayerIds.Remove(packet.Value.SteamId);
                        break;
                    }

                    case MessageType.PlayerPosition:
                    {
                        if (smallPlayerIds.ContainsKey(packet.Value.SteamId))
                        {
                            byte      playerId = smallPlayerIds[packet.Value.SteamId];
                            PlayerRep pr       = GetPlayerRep(playerId);

                            PlayerPositionMessage ppm = new PlayerPositionMessage(msg);
                            pr.head.transform.position  = ppm.headPos;
                            pr.handL.transform.position = ppm.lHandPos;
                            pr.handR.transform.position = ppm.rHandPos;

                            pr.head.transform.rotation  = ppm.headRot;
                            pr.handL.transform.rotation = ppm.lHandRot;
                            pr.handR.transform.rotation = ppm.rHandRot;

                            /*MelonModLogger.Log($@"---------------------
                             * SteamID: {pr.steamId.ToString()}
                             * LeftHand: {ppm.lHandPos.ToString()}
                             * RightHand: {ppm.rHandPos.ToString()}
                             * Head: {ppm.headPos.ToString()}
                             * ---------------------");*/

                            OtherPlayerPositionMessage relayOPPM = new OtherPlayerPositionMessage
                            {
                                headPos  = ppm.headPos,
                                lHandPos = ppm.lHandPos,
                                rHandPos = ppm.rHandPos,

                                headRot  = ppm.headRot,
                                lHandRot = ppm.lHandRot,
                                rHandRot = ppm.rHandRot,
                                playerId = ppm.playerId
                            };
                            ServerSendToAllExcept(relayOPPM, P2PSend.Unreliable, packet.Value.SteamId);
                        }
                        break;
                    }

                    case MessageType.ObjectSync:
                    {
                        ObjectSyncMessage osm = new ObjectSyncMessage(msg);

                        for (int i = 0; i < osm.objectsToSync.Count; i++)
                        {
                            GameObject obj = ObjectIDManager.GetObject(osm.objectsToSync.Keys.ToList()[i]).gameObject;

                            if (!obj)
                            {
                                MelonModLogger.LogError($"Couldn't find object with ID {obj.name}");
                            }
                            else
                            {
                                obj.transform.position = osm.objectsToSync.Values.ToList()[i].Item1;
                                obj.transform.rotation = osm.objectsToSync.Values.ToList()[i].Item2;
                            }
                            MelonModLogger.Log($"got sync message with id: {obj.name}");
                        }
                        break;
                    }

                    default:
                        MelonModLogger.Log("Unknown message type: " + type.ToString());
                        break;
                    }
                }
            }

            /*
             * foreach (var pair in ObjectIDManager.objects)
             * {
             *  ServerSyncedObject sso = pair.Value;
             *  if (sso.NeedsSync())
             *  {
             *      // Sync it
             *      pair.Value.lastSyncedPos = pair.Value.transform.position;
             *      pair.Value.lastSyncedRotation = pair.Value.transform.rotation;
             *
             *      ObjectSyncMessage osm = new ObjectSyncMessage
             *      {
             *          ID = sso.IDHolder.ID,
             *          position = pair.Value.transform.position,
             *          rotation = pair.Value.transform.rotation
             *      };
             *
             *      //ServerSendToAll(osm, P2PSend.Unreliable);
             *  }
             * }
             */

            SendSync();

            if (GlobalStorage.Instance.MasterHMDAndInputController != null)
            {
                OtherPlayerPositionMessage ppm = new OtherPlayerPositionMessage
                {
                    headPos  = GlobalStorage.Instance.MasterHMDAndInputController.camTransform.position,
                    lHandPos = GlobalStorage.Instance.MasterHMDAndInputController.LeftHand.cfjTransform.position,
                    rHandPos = GlobalStorage.Instance.MasterHMDAndInputController.RightHand.cfjTransform.position,

                    headRot  = GlobalStorage.Instance.MasterHMDAndInputController.camTransform.rotation,
                    lHandRot = GlobalStorage.Instance.MasterHMDAndInputController.LeftHand.cfjTransform.rotation,
                    rHandRot = GlobalStorage.Instance.MasterHMDAndInputController.RightHand.cfjTransform.rotation,
                };

                ServerSendToAll(ppm, P2PSend.Unreliable);
            }
        }
Example #11
0
 private void SendToServer(P2PMessage msg, MessageSendType send)
 {
     byte[] msgBytes = msg.GetBytes();
     //SteamNetworking.SendP2PPacket(ServerId, msgBytes, msgBytes.Length, 0, send);
     connection.SendMessage(msg, send);
 }
Example #12
0
 public void SendToServer(P2PMessage msg, P2PSend send)
 {
     byte[] msgBytes = msg.GetBytes();
     SteamNetworking.SendP2PPacket(ServerId, msgBytes, msgBytes.Length, 0, send);
 }