예제 #1
0
        public PlayerShell(Network.PlayerInfo info)
        {
            RWConsole.LogInfo("PlayerShell being created...");

            Graphics   = new PlayerGraphics(info.Player);
            info.Shell = this;
            RWConsole.LogInfo("PlayerShell created.");
        }
예제 #2
0
        private void Client_MessageReceivedEvent(Received data)
        {
            Client.StartReceive(); // Start listening again immediately
            Message receivedMessage = data.Message;

            switch (receivedMessage.Type)
            {
            case MessageType.RemotePlayerAnimation:
                string[] anim      = receivedMessage.Contents.Split('|');
                string   username  = anim[0];
                int      animation = int.Parse(anim[1]);
                int      frame     = int.Parse(anim[2]);

                Player.AnimationIndex animationIndex = (Player.AnimationIndex)animation;
                typeof(Player).GetProperty("animationFrame").SetValue(RemotePlayers[username].Player, frame, null);
                RemotePlayers[username].Animation = animationIndex;
                break;

            case MessageType.RemotePlayerChunkPosition:
                string[] pos = receivedMessage.Contents.Split('|', ',');

                username = pos[0];
                int chunkIndex = int.Parse(pos[1]);

                if (!float.TryParse(pos[4], out float rx))
                {
                    RWConsole.LogError("Bad chunkrotation x");
                }
                if (!float.TryParse(pos[5], out float ry))
                {
                    RWConsole.LogError("Bad chunkrotation y");
                }

                if (!float.TryParse(pos[6], out float velx))
                {
                    RWConsole.LogError("Bad velocity x");
                }
                if (!float.TryParse(pos[7], out float vely))
                {
                    RWConsole.LogError("Bad velocity y");
                }

                Vector2 chunkPosition = new Vector2(float.Parse(pos[2]), float.Parse(pos[3]));
                Vector2 chunkRotation = new Vector2(rx, ry);
                Vector2 chunkVelocity = new Vector2(velx, vely);

                CreateShellClientside(username);
                RemotePlayers[username].Creature.bodyChunks[chunkIndex].pos = chunkPosition;
                RemotePlayers[username].Creature.bodyChunks[chunkIndex].Rotation.Set(rx, ry);
                RemotePlayers[username].Creature.bodyChunks[chunkIndex].vel = chunkVelocity;
                break;

            default:
                RWConsole.LogError($"[CLIENT] Unable to handle message of type: {receivedMessage.Type} with contents: {receivedMessage.Contents} from: {data.Sender}");
                break;
            }
        }
예제 #3
0
        /// <summary>
        /// Makes the current instance of RainWorld a server.
        /// </summary>
        public static void SetupServer()
        {
            RWConsole.LogInfo("Starting server...");

            ConnectedClients = new Dictionary <IPEndPoint, PlayerInfo>();

            Server = new UdpListener();
            Server.StartReceive();
            IsServer = true;
        }
예제 #4
0
        /// <summary>
        /// [Clientside] Connects to the server.
        /// </summary>
        /// <param name="address">Server address</param>
        /// <param name="port">Server port</param>
        public static void SetupClient(string address, int port)
        {
            RWConsole.LogInfo("Attempting connection to " + address);

            RemotePlayers = new Dictionary <string, PlayerInfo>();

            Client = UdpUser.ConnectTo(address, port);
            Client.StartReceive();
            IsClient  = true;
            Connected = true;
        }
예제 #5
0
        public ClientMonkScript()
        {
            Instance = this;
            Client.MessageReceivedEvent += Client_MessageReceivedEvent;

            Parser.AddRule(MessageType.HandshakeAck, (Message receivedMessage, Received data) => {
                RWConsole.LogInfo("Handshake acknowledged!");
            });
            Parser.AddRule(MessageType.RemotePlayerAnimation, (Message receivedMessage, Received data) => {
                string[] anim   = receivedMessage.Contents.Split('|');
                string username = anim[0];
                int animation   = int.Parse(anim[1]);
                int frame       = int.Parse(anim[2]);

                Player.AnimationIndex animationIndex = (Player.AnimationIndex)animation;
                typeof(Player).GetProperty("animationFrame").SetValue(RemotePlayers[username].Player, frame, null);
                RemotePlayers[username].Animation = animationIndex;
            });
            Parser.AddRule(MessageType.RemotePlayerChunkPosition, (Message receivedMessage, Received data) => {
                string[] pos = receivedMessage.Contents.Split('|', ',');

                string username = pos[0];
                int chunkIndex  = int.Parse(pos[1]);

                if (!float.TryParse(pos[4], out float rx))
                {
                    RWConsole.LogError("Bad chunkrotation x");
                }
                if (!float.TryParse(pos[5], out float ry))
                {
                    RWConsole.LogError("Bad chunkrotation y");
                }

                if (!float.TryParse(pos[6], out float velx))
                {
                    RWConsole.LogError("Bad velocity x");
                }
                if (!float.TryParse(pos[7], out float vely))
                {
                    RWConsole.LogError("Bad velocity y");
                }

                Vector2 chunkPosition = new Vector2(float.Parse(pos[2]), float.Parse(pos[3]));
                Vector2 chunkRotation = new Vector2(rx, ry);
                Vector2 chunkVelocity = new Vector2(velx, vely);

                CreateShellClientside(username);
                RemotePlayers[username].Creature.bodyChunks[chunkIndex].pos = chunkPosition;
                RemotePlayers[username].Creature.bodyChunks[chunkIndex].Rotation.Set(rx, ry);
                RemotePlayers[username].Creature.bodyChunks[chunkIndex].vel = chunkVelocity;
            });
        }
예제 #6
0
        public override void OnEnable()
        {
            base.OnEnable();
            Debug.Log("Using monkland.");

            RWConsole.Initialize();

            AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
            On.RainWorldGame.ExitGame           += RainWorldGame_ExitGame;

            PlayerManager.Hook();
            PauseMenuHooks.Hook();
            MainMenuHooks.Hook();
        }
예제 #7
0
        private void Client_MessageReceivedEvent(Received data)
        {
            Client.StartReceive(); // Start listening again immediately
            Message receivedMessage = data.Message;

            if (Parser.TryParse(receivedMessage, data))
            {
                ;                                         // Parse message
            }
            else
            {
                RWConsole.LogError($"Couldn't parse message with type {receivedMessage.Type} and contents {receivedMessage.Contents}");
            }
        }
예제 #8
0
        private void Server_MessageReceivedEvent(Received data)
        {
            Server.StartReceive(); // Start listening again immediately
            Message receivedMessage = data.Message;

            CreateShellServerside(data.Sender);

            if (Parser.TryParse(receivedMessage, data))
            {
                ;                                         // Parse message
            }
            else
            {
                RWConsole.LogError($"Unable to parse message with type {receivedMessage.Type} with contents {receivedMessage.Contents}");
            }
        }
예제 #9
0
        /// <summary>
        /// [Serverside] Creates a <see cref="PlayerShell"/> with a random username
        /// </summary>
        /// <param name="sender"></param>
        private void CreateShellServerside(System.Net.IPEndPoint sender)
        {
            if (ConnectedClients.Keys.Where(x => x.Equals(sender)).Count() == 0)
            {
                RWConsole.LogInfo("Creating PlayerInfo...");
                ConnectedClients[sender] = new PlayerInfo()
                {
                    ID = GetNewID(),
                };

                RWConsole.LogInfo("Creating abstract player...");
                AbstractCreature abstractPlayer = null;
                try {
                    abstractPlayer = new AbstractCreature
                                         (Game.world, StaticWorld.GetCreatureTemplate(CreatureTemplate.Type.Slugcat), null, new WorldCoordinate(), new EntityID());
                }
                catch (Exception e) {
                    if (Game == null)
                    {
                        RWConsole.LogError("Game is null!");
                    }
                    RWConsole.LogError(e);
                }
                RWConsole.LogInfo("Created abstract player.");

                RWConsole.LogInfo("Creating PlayerState...");
                PlayerState playerState = new PlayerState(abstractPlayer, 0, 1, false);
                abstractPlayer.state = playerState;
                RWConsole.LogInfo("Created PlayerState.");

                RWConsole.LogInfo("Realizing player...");
                try {
                    abstractPlayer?.Realize();
                    ConnectedClients[sender].Player = abstractPlayer?.realizedCreature as Player;
                    if (ConnectedClients[sender].Player == null)
                    {
                        RWConsole.LogError("Player is null!");
                    }
                }
                catch (Exception e) { RWConsole.LogError(e); }
                RWConsole.LogInfo("Realized player.");

                PlayerShell playerShell = new PlayerShell(ConnectedClients[sender]);
                Game.Players[0].Room.realizedRoom.AddObject(playerShell);
                RWConsole.LogInfo("Created PlayerInfo");
            }
        }
예제 #10
0
        /// <summary>
        /// [Clientside] Creates a <see cref="PlayerShell"/>
        /// </summary>
        /// <param name="username"></param>
        private void CreateShellClientside(string username)
        {
            if (!RemotePlayers.ContainsKey(username))
            {
                RWConsole.LogInfo($"Creating PlayerInfo for {username}...");
                RemotePlayers[username] = new PlayerInfo();

                RWConsole.LogInfo("Creating abstract player...");
                AbstractCreature abstractPlayer = null;
                try {
                    abstractPlayer = new AbstractCreature
                                         (Game.world, StaticWorld.GetCreatureTemplate(CreatureTemplate.Type.Slugcat), null, new WorldCoordinate(), new EntityID());
                }
                catch (Exception e) {
                    if (Game == null)
                    {
                        RWConsole.LogError("Game is null!");
                    }
                    RWConsole.LogError(e);
                }
                RWConsole.LogInfo("Created abstract player.");

                RWConsole.LogInfo("Creating PlayerState...");
                PlayerState playerState = new PlayerState(abstractPlayer, 0, 1, false);
                abstractPlayer.state = playerState;
                RWConsole.LogInfo("Created PlayerState.");

                RWConsole.LogInfo("Realizing player...");
                try {
                    abstractPlayer?.Realize();
                    RemotePlayers[username].Player = abstractPlayer?.realizedCreature as Player;
                    if (RemotePlayers[username].Player == null)
                    {
                        RWConsole.LogError("Player is null!");
                    }
                }
                catch (Exception e) { RWConsole.LogError(e); }
                RWConsole.LogInfo("Realized player.");

                PlayerShell playerShell = new PlayerShell(RemotePlayers[username]);
                Game.Players[0].Room.realizedRoom.AddObject(playerShell);
                RWConsole.LogInfo($"Created PlayerInfo for {username}");
            }
        }
예제 #11
0
        /// <summary>
        /// <para>[Clientside] Sends a message to the server.</para>
        /// <para>[Serverside] Sends a message to all clients.</para>
        /// </summary>
        /// <param name="message"></param>
        public static void SendMessage(Message message)
        {
            if (!IsClient && !IsServer)
            {
                RWConsole.LogError("Can't send when disconnected.");
                return;
            }

            if (IsServer)
            {
                foreach (IPEndPoint ipep in ConnectedClients.Keys)
                {
                    Server.Reply(message, ipep);
                }
            }
            else
            {
                Client.Send(message);
            }
        }
예제 #12
0
 public void OnEnable()
 {
     RWConsole.LogInfo("Sending handshake...");
     Client.Send(new Message(MessageType.Handshake, ""));
 }
예제 #13
0
        public ServerMonkScript()
        {
            Instance = this;
            Server.MessageReceivedEvent += Server_MessageReceivedEvent;

            Parser.AddRule(MessageType.PlayerAnimation, (Message receivedMessage, Received data) => {
                string[] anim = receivedMessage.Contents.Split('|');
                int animation = int.Parse(anim[0]);
                int frame     = int.Parse(anim[1]);

                ConnectedClients[data.Sender].Animation = (Player.AnimationIndex)animation;
                typeof(Player).GetProperty("animationFrame").SetValue(ConnectedClients[data.Sender].Player, frame, null);
                SendMessageExcluding(new Message(MessageType.RemotePlayerAnimation, $"{ConnectedClients[data.Sender].ID}|{animation}"), data.Sender);
            });
            Parser.AddRule(MessageType.PlayerChunkPosition, (Message receivedMessage, Received data) => {
                string[] pos = receivedMessage.Contents.Split('|', ',');

                if (!int.TryParse(pos[0], out int chunkIndex))
                {
                    RWConsole.LogError("Bad chunkindex");
                }
                if (!float.TryParse(pos[1], out float x))
                {
                    RWConsole.LogError("Bad chunkposition x");
                }
                if (!float.TryParse(pos[2], out float y))
                {
                    RWConsole.LogError("Bad chunkposition y");
                }

                if (!float.TryParse(pos[3], out float rx))
                {
                    RWConsole.LogError("Bad chunkrotation x");
                }
                if (!float.TryParse(pos[4], out float ry))
                {
                    RWConsole.LogError("Bad chunkrotation y");
                }
                if (!float.TryParse(pos[5], out float velx))
                {
                    RWConsole.LogError("Bad velocity x");
                }
                if (!float.TryParse(pos[6], out float vely))
                {
                    RWConsole.LogError("Bad velocity y");
                }

                chunkIndex            = int.Parse(pos[0]);
                Vector2 chunkPosition = new Vector2(x, y);
                Vector2 chunkRotation = new Vector2(rx, ry);
                Vector2 chunkVelocity = new Vector2(velx, vely);

                ConnectedClients[data.Sender].Creature.bodyChunks[chunkIndex].pos = chunkPosition;
                ConnectedClients[data.Sender].Creature.bodyChunks[chunkIndex].Rotation.Set(rx, ry);
                ConnectedClients[data.Sender].Creature.bodyChunks[chunkIndex].vel = chunkVelocity;

                SendMessageExcluding(new Message(
                                         MessageType.RemotePlayerChunkPosition, $"{ConnectedClients[data.Sender].ID}|{chunkIndex}|" +
                                         $"{chunkPosition.x},{chunkPosition.y},{chunkRotation.x},{chunkRotation.y}"
                                         ),
                                     data.Sender);
            });
            Parser.AddRule(MessageType.Handshake, (Message receivedMessage, Received data) => {
                SendMessageTo(new Message(MessageType.HandshakeAck, ""), data.Sender);
            });
        }
예제 #14
0
        private void Server_MessageReceivedEvent(Received data)
        {
            Server.StartReceive(); // Start listening again immediately
            Message receivedMessage = data.Message;

            CreateShellServerside(data.Sender);

            switch (receivedMessage.Type)
            {
            case MessageType.PlayerAnimation:
                string[] anim      = receivedMessage.Contents.Split('|');
                int      animation = int.Parse(anim[0]);
                int      frame     = int.Parse(anim[1]);

                ConnectedClients[data.Sender].Animation = (Player.AnimationIndex)animation;
                typeof(Player).GetProperty("animationFrame").SetValue(ConnectedClients[data.Sender].Player, frame, null);
                SendMessageExcluding(new Message(MessageType.RemotePlayerAnimation, $"{ConnectedClients[data.Sender].Username}|{animation}"), data.Sender);
                break;

            case MessageType.PlayerChunkPosition:
                string[] pos = receivedMessage.Contents.Split('|', ',');

                if (!int.TryParse(pos[0], out int chunkIndex))
                {
                    RWConsole.LogError("Bad chunkindex");
                }
                if (!float.TryParse(pos[1], out float x))
                {
                    RWConsole.LogError("Bad chunkposition x");
                }
                if (!float.TryParse(pos[2], out float y))
                {
                    RWConsole.LogError("Bad chunkposition y");
                }

                if (!float.TryParse(pos[3], out float rx))
                {
                    RWConsole.LogError("Bad chunkrotation x");
                }
                if (!float.TryParse(pos[4], out float ry))
                {
                    RWConsole.LogError("Bad chunkrotation y");
                }
                if (!float.TryParse(pos[5], out float velx))
                {
                    RWConsole.LogError("Bad velocity x");
                }
                if (!float.TryParse(pos[6], out float vely))
                {
                    RWConsole.LogError("Bad velocity y");
                }

                chunkIndex = int.Parse(pos[0]);
                Vector2 chunkPosition = new Vector2(x, y);
                Vector2 chunkRotation = new Vector2(rx, ry);
                Vector2 chunkVelocity = new Vector2(velx, vely);

                ConnectedClients[data.Sender].Creature.bodyChunks[chunkIndex].pos = chunkPosition;
                ConnectedClients[data.Sender].Creature.bodyChunks[chunkIndex].Rotation.Set(rx, ry);
                ConnectedClients[data.Sender].Creature.bodyChunks[chunkIndex].vel = chunkVelocity;

                SendMessageExcluding(new Message(
                                         MessageType.RemotePlayerChunkPosition, $"{ConnectedClients[data.Sender].Username}|{chunkIndex}|" +
                                         $"{chunkPosition.x},{chunkPosition.y},{chunkRotation.x},{chunkRotation.y}"
                                         ),
                                     data.Sender);
                break;

            case MessageType.Handshake:
                SendMessageTo(new Message(MessageType.HandshakeAck, ""), data.Sender);
                break;

            default:
                RWConsole.LogError($"[SERVER] Unable to handle message of type: {receivedMessage.Type} with contents: {receivedMessage.Contents} from: {data.Sender}");
                break;
            }
        }