// Starts a server or client based on the command args
 private void CheckArgsForConnectionInfo()
 {
     if (MDArguments.HasArg(ARG_STANDALONE))
     {
         StartStandalone();
     }
     // Expects -server=[port]
     else if (MDArguments.HasArg(ARG_SERVER))
     {
         int Port = MDArguments.GetArgInt(ARG_SERVER);
         StartServer(Port);
     }
     // Expects -client=[IPAddress:Port]
     else if (MDArguments.HasArg(ARG_CLIENT))
     {
         string   ClientArg = MDArguments.GetArg(ARG_CLIENT);
         string[] HostPort  = ClientArg.Split(":");
         if (HostPort.Length == 2)
         {
             StartClient(HostPort[0], HostPort[1].ToInt());
         }
         else
         {
             MDLog.Error(LOG_CAT,
                         $"Failed to parse client arg {ClientArg}, expecting -{ARG_CLIENT}=[IPAddress:Port]");
         }
     }
 }
        /// <summary>
        /// Spawn a network node
        /// </summary>
        /// <param name="ScenePath">The path to the scene to spawn</param>
        /// <param name="Parent">The parent that the new instance will be a child of</param>
        /// <param name="NodeName">The name of the new node</param>
        /// <param name="UseRandomName">If set to true a random number will be added at the end of the node name</param>
        /// <param name="NetworkMaster">The peer that should own this, default is server</param>
        /// <param name="SpawnPos">Where the spawn this node</param>
        /// <returns>The new node</returns>
        public Node SpawnNetworkedNode(string ScenePath, Node Parent, string NodeName, bool UseRandomName = true,
                                       int NetworkMaster = -1, Vector3?SpawnPos = null)
        {
            if (this.IsMaster() == false)
            {
                MDLog.Error(LOG_CAT, "Only server can spawn networked nodes");
                return(null);
            }

            if (!Parent.IsInsideTree())
            {
                MDLog.Error(LOG_CAT, $"Parent [{Parent.Name}] is not inside the tree");
                return(null);
            }

            NodeName = BuildNodeName(NodeName, UseRandomName);

            int    NodeMaster = NetworkMaster != -1 ? NetworkMaster : MDStatics.GetPeerId();
            string ParentPath = Parent.GetPath();

            Vector3 SpawnPosVal = SpawnPos.GetValueOrDefault();

            if (MDStatics.IsNetworkActive())
            {
                Rpc(nameof(SpawnNodeScene), ScenePath, ParentPath, NodeName, NodeMaster, SpawnPosVal);
            }

            return(SpawnNodeScene(ScenePath, ParentPath, NodeName, NodeMaster, SpawnPosVal));
        }
Beispiel #3
0
        private void GenerateConfigFile(string Source, string Target)
        {
            string existingTarget = FindFile(Target);

            if (existingTarget == "")
            {
                string SourceFilePath = FindFile(Source);
                File   SourceFile     = new File();
                SourceFile.Open(SourceFilePath, File.ModeFlags.Read);
                string SourceText = SourceFile.GetAsText();
                SourceFile.Close();

                if (SourceText == "")
                {
                    MDLog.Error(LOG_CAT, $"Failed to read config from {SourceFilePath}");
                    return;
                }

                string TargetFilePath = $"res://{Target}";
                File   TargetFile     = new File();
                TargetFile.Open(TargetFilePath, File.ModeFlags.Write);

                TargetFile.StoreString(SourceText);
                TargetFile.Close();

                MDLog.Info(LOG_CAT, $"Copied config file from {SourceFilePath} to {TargetFilePath}");
            }
            else
            {
                MDLog.Info(LOG_CAT, $"Config file {existingTarget} already exists");
            }
        }
        // Create and initialize the player object
        private MDPlayerInfo GetOrCreatePlayerObject(int PeerId)
        {
            if (Players.ContainsKey(PeerId))
            {
                return(Players[PeerId]);
            }

            Type PlayerType = GameInstance.GetPlayerInfoType();

            if (!MDStatics.IsSameOrSubclass(PlayerType, typeof(MDPlayerInfo)))
            {
                MDLog.Error(LOG_CAT, $"Provided player type [{PlayerType.Name}] is not a subclass of MDPlayerInfo");
                return(null);
            }

            MDPlayerInfo Player = Activator.CreateInstance(PlayerType) as MDPlayerInfo;

            Player.SetPeerId(PeerId);
            Player.PauseMode = PauseModeEnum.Process;
            AddChild(Player);
            Players.Add(PeerId, Player);

            OnPlayerInfoCreated(Player);

            return(Player);
        }
        public bool StartServer(int Port, int MaxPlayers = DEFAULT_MAX_PLAYERS)
        {
            NetworkedMultiplayerENet peer = new NetworkedMultiplayerENet();

            peer.Connect("peer_connected", this, nameof(ServerOnPeerConnected));
            peer.Connect("peer_disconnected", this, nameof(ServerOnPeerDisconnected));
            ConfigurePeer(peer);

            Error error   = peer.CreateServer(Port, MaxPlayers);
            bool  Success = error == Error.Ok;

            MDLog.CLog(Success, LOG_CAT, MDLogLevel.Info,
                       $"Starting server on port {Port} with {MaxPlayers} max players.");
            MDLog.CLog(!Success, LOG_CAT, MDLogLevel.Error, $"Failed to start server on port {Port}");

            if (Success)
            {
                UPNPPort = Port;
                SetNetworkPeer(peer);
                ServerOnStarted();
            }
            else
            {
                MDLog.Error(LOG_CAT, "Failed to start server");
                OnSessionFailedEvent();
            }

            return(Success);
        }
Beispiel #6
0
        /// <summary>
        /// Creates an instance of the type based on the base class T
        /// </summary>
        /// <param name="Type">The type to instantiate</param>
        /// <returns>The instance created or null if it fails</returns>
        public static T CreateTypeInstance <T>(Type Type) where T : class
        {
            if (!IsSameOrSubclass(Type, typeof(T)))
            {
                MDLog.Error(LOG_CAT, $"Type [{Type.Name}] is not a subclass of [{typeof(T).Name}]");
                return(null);
            }

            return(Activator.CreateInstance(Type) as T);
        }
        private void RemoveAndFreeNode(string NodePath)
        {
            Node NetworkedNode = GetNodeOrNull(NodePath);

            if (NetworkedNode == null)
            {
                MDLog.Error(LOG_CAT, $"Could not find Node with path {NodePath}");
                return;
            }

            OnNetworkNodeRemoved(NetworkedNode);
            NetworkedNode.RemoveAndFree();
        }
Beispiel #8
0
        public static void PopulateBindNodes(Node Instance)
        {
            List <MemberInfo> Members = MDStatics.GetTypeMemberInfos(Instance);

            foreach (MemberInfo Member in Members)
            {
                MDBindNode BindAttr = Member.GetCustomAttribute(typeof(MDBindNode)) as MDBindNode;
                if (BindAttr == null)
                {
                    continue;
                }

                Type         MemberType = null;
                FieldInfo    Field      = Member as FieldInfo;
                PropertyInfo Property   = Member as PropertyInfo;
                if (Field != null)
                {
                    MemberType = Field.FieldType;
                }
                else if (Property != null)
                {
                    MemberType = Property.PropertyType;
                }

                if (!MDStatics.IsSameOrSubclass(MemberType, typeof(Node)))
                {
                    MDLog.Error(LOG_CAT,
                                $"Not Node-Type field [{Member.Name}] on Node {Instance.Name} with Type [{Instance.GetType().Name}] was marked with [MDBindNode()]");
                    continue;
                }

                string PathToNode = BindAttr.GetNodePath(Member.Name);
                Node   BoundNode  = FindNode(Instance, PathToNode);
                if (BoundNode == null)
                {
                    continue;
                }

                if (Field != null)
                {
                    Field.SetValue(Instance, BoundNode);
                }
                else if (Property != null)
                {
                    Property.SetValue(Instance, BoundNode);
                }
            }
        }
        /// <summary>
        /// Get the value of this member
        /// </summary>
        /// <param name="member">The member</param>
        /// <param name="Instance">The instance to get the value of</param>
        /// <returns>The value of the member in the instance</returns>
        public static object GetValue(this MemberInfo member, object Instance)
        {
            switch (member.MemberType)
            {
            case MemberTypes.Field:
                return(((FieldInfo)member).GetValue(Instance));

            case MemberTypes.Property:
                return(((PropertyInfo)member).GetValue(Instance));

            default:
                MDLog.Error(LOG_CAT,
                            $"Input MemberInfo was of type {member.MemberType.ToString()}, it should be of type FieldInfo or PropertyInfo");
                break;
            }
            return(null);
        }
        /// <summary>
        /// Sets the value of this member
        /// </summary>
        /// <param name="member">The member</param>
        /// <param name="Instance">The instance to set the value for</param>
        /// <param name="Value">The value</param>
        public static void SetValue(this MemberInfo member, object Instance, object Value)
        {
            switch (member.MemberType)
            {
            case MemberTypes.Field:
                ((FieldInfo)member).SetValue(Instance, Value);
                break;

            case MemberTypes.Property:
                ((PropertyInfo)member).SetValue(Instance, Value);
                break;

            default:
                MDLog.Error(LOG_CAT,
                            $"Input MemberInfo was of type {member.MemberType.ToString()}, it should be of type FieldInfo or PropertyInfo");
                break;
            }
        }
        private Node SpawnNodeType(string NodeTypeString, string ParentPath, string NodeName, int NetworkMaster,
                                   Vector3 SpawnPos)
        {
            MDLog.Log(LOG_CAT, MDLogLevel.Debug,
                      $"Spawning Node. Type: {NodeTypeString} ParentPath: {ParentPath} Name: {NodeName} Master: {NetworkMaster}");
            Node Parent = GetNodeOrNull(ParentPath);

            if (Parent == null)
            {
                MDLog.Error(LOG_CAT, $"Could not find Parent with path {ParentPath}");
                return(null);
            }

            Type NodeType = Type.GetType(NodeTypeString);

            if (NodeType == null)
            {
                MDLog.Error(LOG_CAT, $"Could not find Type {NodeTypeString}");
                return(null);
            }

            Node NewNode = Activator.CreateInstance(NodeType) as Node;

            NewNode.Name = NodeName;
            NewNode.SetNetworkMaster(NetworkMaster);
            NetworkedTypes.Add(NewNode, NodeTypeString);
            OrderedNetworkedNodes.Add(NewNode);

            Node2D  NewNode2D      = NewNode as Node2D;
            Spatial NewNodeSpatial = NewNode as Spatial;

            if (NewNode2D != null)
            {
                NewNode2D.Position = SpawnPos.To2D();
            }
            else if (NewNodeSpatial != null)
            {
                NewNodeSpatial.Translation = SpawnPos;
            }

            Parent.AddChild(NewNode);
            OnNetworkNodeAdded(NewNode);
            return(NewNode);
        }
        private Node SpawnNodeScene(string ScenePath, string ParentPath, string NodeName, int NetworkMaster,
                                    Vector3 SpawnPos)
        {
            MDLog.Log(LOG_CAT, MDLogLevel.Debug,
                      $"Spawning Node. Scene: {ScenePath} ParentPath: {ParentPath} Name: {NodeName} Master: {NetworkMaster}");
            Node Parent = GetNodeOrNull(ParentPath);

            if (Parent == null)
            {
                MDLog.Error(LOG_CAT, $"Could not find Parent with path: {ParentPath}");
                return(null);
            }

            PackedScene Scene = LoadScene(ScenePath);

            if (Scene == null)
            {
                return(null);
            }

            Node NewNode = Scene.Instance();

            NewNode.Name = NodeName;
            NewNode.SetNetworkMaster(NetworkMaster);
            NetworkedScenes.Add(NewNode, ScenePath);
            OrderedNetworkedNodes.Add(NewNode);

            Node2D  NewNode2D      = NewNode as Node2D;
            Spatial NewNodeSpatial = NewNode as Spatial;

            if (NewNode2D != null)
            {
                NewNode2D.Position = SpawnPos.To2D();
            }
            else if (NewNodeSpatial != null)
            {
                NewNodeSpatial.Translation = SpawnPos;
            }

            Parent.AddChild(NewNode);
            OnNetworkNodeAdded(NewNode);
            return(NewNode);
        }
Beispiel #13
0
        private static File GetHistoryFile()
        {
            if (CreateHistoryDirectoryIfNotExists(HISTORY_DIR))
            {
                string FullFilePath = HISTORY_DIR + HISTORY_FILE;
                File   CmdFile      = new File();
                if (!CmdFile.FileExists(FullFilePath))
                {
                    CmdFile.Open(FullFilePath, File.ModeFlags.Write);
                    CmdFile.Close();
                }

                CmdFile.Open(FullFilePath, File.ModeFlags.ReadWrite);
                return(CmdFile);
            }

            MDLog.Error(LOG_CAT, "Failed to create command history directory.");
            return(null);
        }
Beispiel #14
0
        public override void Replicate(int JoinInProgressPeerId, bool IsIntervalReplicationTime)
        {
            IMDCommandReplicator CommandReplicator = GetCommandReplicator();
            Node Instance = NodeRef.GetRef() as Node;

            if (CommandReplicator == null)
            {
                MDLog.Error(LOG_CAT, $"Command replicator is null for member {Instance.GetPath()}#{Member.Name}");
                return;
            }

            if ((GetReplicatedType() == MDReplicatedType.Interval && IsIntervalReplicationTime) || (GetReplicatedType() == MDReplicatedType.OnChange))
            {
                // We do a check here to see if anything has updated
                GetCommandReplicator().MDShouldBeReplicated();
                List <object[]> commands = GetCommandReplicator().MDGetCommands();
                if (commands.Count > 0)
                {
                    // Do replication to all except joining peer if we got one
                    commands.ForEach(value =>
                    {
                        foreach (int PeerId in GameSession.GetAllPeerIds())
                        {
                            if (PeerId != JoinInProgressPeerId && PeerId != MDStatics.GetPeerId())
                            {
                                ReplicateCommandToPeer(value, PeerId);
                            }
                        }
                    });

                    CheckCallLocalOnChangeCallback();
                }
            }

            if (JoinInProgressPeerId != -1)
            {
                // Replicate current data to joining peer and send current command we are at
                List <object[]> newPlayerCommands = CommandReplicator.MDGetCommandsForNewPlayer();
                newPlayerCommands.ForEach(value => ReplicateCommandToPeer(value, JoinInProgressPeerId));
            }
        }
        /// <summary>
        /// Gets the underlying type of a member
        /// </summary>
        /// <param name="member">The member to find the type for</param>
        /// <returns>The underlying type</returns>
        public static Type GetUnderlyingType(this MemberInfo member)
        {
            switch (member.MemberType)
            {
            case MemberTypes.Event:
                return(((EventInfo)member).EventHandlerType);

            case MemberTypes.Field:
                return(((FieldInfo)member).FieldType);

            case MemberTypes.Method:
                return(((MethodInfo)member).ReturnType);

            case MemberTypes.Property:
                return(((PropertyInfo)member).PropertyType);

            default:
                MDLog.Error(LOG_CAT,
                            $"Input MemberInfo was of type {member.MemberType.ToString()}, it should be of type EventInfo, FieldInfo, MethodInfo, or PropertyInfo");
                return(null);
            }
        }
        /// <summary>
        /// Spawn a network node
        /// </summary>
        /// <param name="NodeType">The type of node to spawn</param>
        /// <param name="Parent">The parent that the new instance will be a child of</param>
        /// <param name="NodeName">The name of the new node</param>
        /// <param name="UseRandomName">If set to true a random number will be added at the end of the node name</param>
        /// <param name="NetworkMaster">The peer that should own this, default is server</param>
        /// <param name="SpawnPos">Where the spawn this node</param>
        /// <returns>The new node</returns>
        public Node SpawnNetworkedNode(Type NodeType, Node Parent, string NodeName, bool UseRandomName = true,
                                       int NetworkMaster = -1, Vector3?SpawnPos = null)
        {
            if (this.IsMaster() == false)
            {
                MDLog.Error(LOG_CAT, "Only server can spawn networked nodes");
                return(null);
            }

            if (!MDStatics.IsSameOrSubclass(NodeType, typeof(Node)))
            {
                MDLog.Error(LOG_CAT, $"Provided type [{NodeType.Name}] is not a subclass of Node");
                return(null);
            }

            if (!Parent.IsInsideTree())
            {
                MDLog.Error(LOG_CAT, $"Parent [{Parent.Name}] is not inside the tree");
                return(null);
            }

            NodeName = BuildNodeName(NodeName, UseRandomName);

            int    NodeMaster     = NetworkMaster != -1 ? NetworkMaster : MDStatics.GetPeerId();
            string NodeTypeString = NodeType.AssemblyQualifiedName;
            string ParentPath     = Parent.GetPath();

            Vector3 SpawnPosVal = SpawnPos.GetValueOrDefault();

            if (MDStatics.IsNetworkActive())
            {
                Rpc(nameof(SpawnNodeType), NodeTypeString, ParentPath, NodeName, NodeMaster, SpawnPosVal);
            }

            return(SpawnNodeType(NodeTypeString, ParentPath, NodeName, NodeMaster, SpawnPosVal));
        }
Beispiel #17
0
        /// <summary>
        /// Call a registered command via its name
        /// </summary>
        /// <param name="Command">The command to call</param>
        /// <returns>True if executed, false if not</returns>
        public static bool InvokeCommand(string Command)
        {
            string[] Args = Command.Split(" ", false);
            if (Args.Length == 0)
            {
                // empty string
                return(false);
            }

            MDLog.Info(LOG_CAT, Command);
            AddCommandToHistory(Command);

            string CmdName = Args[0].ToLower();

            if (!_commandMap.ContainsKey(CmdName))
            {
                MDLog.Error(LOG_CAT, $"Command not found: [{Command}]");
                return(false);
            }

            CommandInfo CmdInfo = _commandMap[CmdName];

            ParameterInfo[] Params = CmdInfo.Method.GetParameters();
            object[]        ParamArray;

            // Should we use the default args?
            if (Params.Length > 0 && Args.Length == 1 && CmdInfo.DefaultArgs.Length == Params.Length)
            {
                ParamArray = CmdInfo.DefaultArgs;
            }
            else
            {
                if (Args.Length - 1 != Params.Length)
                {
                    // Wrong number of arguments
                    return(false);
                }

                ParamArray = new object[Args.Length - 1];
                Array.Copy(Args, 1, ParamArray, 0, ParamArray.Length);
            }

            // Convert the strings to the appropriate type
            List <object> CmdParams = new List <object>();
            int           ArgIndex  = 0;

            foreach (ParameterInfo ParamInfo in Params)
            {
                if (ParamInfo.ParameterType.IsEnum)
                {
                    object Param = Enum.Parse(ParamInfo.ParameterType, ParamArray[ArgIndex++] as string, true);
                    CmdParams.Add(Param);
                }
                else
                {
                    object Param = Convert.ChangeType(ParamArray[ArgIndex++], ParamInfo.ParameterType);
                    CmdParams.Add(Param);
                }
            }

            CmdInfo.Method.Invoke(CmdInfo.Instance, CmdParams.ToArray());

            return(true);
        }
 private void ClientOnServerDisconnect()
 {
     MDLog.Error(LOG_CAT, "Client was disconnected from server");
     Disconnect();
 }
 private void ClientOnFailedToConnect()
 {
     MDLog.Error(LOG_CAT, "Client failed to connect to server");
     OnSessionFailedEvent();
 }