public PlayerShell(Network.PlayerInfo info) { RWConsole.LogInfo("PlayerShell being created..."); Graphics = new PlayerGraphics(info.Player); info.Shell = this; RWConsole.LogInfo("PlayerShell created."); }
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; } }
/// <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; }
/// <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; }
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; }); }
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(); }
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}"); } }
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}"); } }
/// <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"); } }
/// <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}"); } }
/// <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); } }
public void OnEnable() { RWConsole.LogInfo("Sending handshake..."); Client.Send(new Message(MessageType.Handshake, "")); }
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); }); }
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; } }