// 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)); }
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); }
/// <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(); }
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); }
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); }
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)); }
/// <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(); }