Exemple #1
0
        public void SendGear(uint connectionToSend, NetworkingSockets server)
        {
            byte[] sendData = new byte[gearStream.Count + 6];

            if (sendData.Length > Library.maxMessageSize)
            {
                ushort totalMessages = (ushort)Math.Ceiling((double)sendData.Length / Library.maxMessageSize);

                byte[] textureDataArray = gearStream.ToArray();

                for (ushort currentMessage = 0; currentMessage < totalMessages; currentMessage++)
                {
                    int startIndex = currentMessage == 0 ? 0 : currentMessage * (Library.maxMessageSize - 6);

                    byte[] messagePart = new byte[Math.Min(Library.maxMessageSize, textureDataArray.Length - (Library.maxMessageSize - 6) * currentMessage + 6)];
                    messagePart[0] = (byte)OpCode.Texture;
                    Array.Copy(BitConverter.GetBytes(currentMessage), 0, messagePart, 1, 2);
                    Array.Copy(BitConverter.GetBytes(totalMessages - 1), 0, messagePart, 3, 2);
                    Array.Copy(textureDataArray, startIndex, messagePart, 5, messagePart.Length - 6);
                    messagePart[messagePart.Length - 1] = playerID;

                    server.SendMessageToConnection(connectionToSend, messagePart, SendFlags.Reliable);
                }
            }
            else
            {
                sendData[0] = (byte)OpCode.Texture;
                Array.Copy(BitConverter.GetBytes((ushort)0), 0, sendData, 1, 2);
                Array.Copy(BitConverter.GetBytes((ushort)0), 0, sendData, 3, 2);
                Array.Copy(gearStream.ToArray(), 0, sendData, 5, gearStream.Count);
                sendData[sendData.Length - 1] = playerID;

                server.SendMessageToConnection(connectionToSend, sendData, SendFlags.Reliable);
            }
        }
 public void Send(Byte[] data, SendFlags flags, OnSent onSent)
 {
     if (connected)
     {
         client.SendMessageToConnection(connection, data, flags);
         onSent?.Invoke();
     }
 }
Exemple #3
0
        public void StatusCallbackFunction(ref StatusInfo info, IntPtr context)
        {
            switch (info.connectionInfo.state)
            {
            case ConnectionState.None:
                break;

            case ConnectionState.Connecting: {
                if (info.connectionInfo.listenSocket != listenSocket)
                {
                    mainServer.StatusCallbackFunction(ref info, context);
                    break;
                }

                //Console.WriteLine("connecting on file server");

                if (mainServer.bannedIPs.Contains(info.connectionInfo.address.GetIP()))
                {
                    //Console.WriteLine("Ban player attempted to connect to the server, IP: {0}", info.connectionInfo.address.GetIP());
                    server.CloseConnection(info.connection);
                }
                else
                {
                    server.AcceptConnection(info.connection);
                    server.SetConnectionPollGroup(pollGroup, info.connection);
                }
            } break;

            case ConnectionState.Connected: {
                if (info.connectionInfo.listenSocket != listenSocket)
                {
                    mainServer.StatusCallbackFunction(ref info, context);
                    break;
                }

                if (mainServer.motdBytes != null)
                {
                    server.SendMessageToConnection(info.connection, mainServer.motdBytes);
                }

                //Console.WriteLine("connected on file server");
            } break;

            case ConnectionState.ClosedByPeer:
            case ConnectionState.ProblemDetectedLocally:
                mainServer.RemovePlayer(info.connection);
                break;
            }
        }
Exemple #4
0
        private static void RemovePlayer(uint connection, int ID = -1, bool kicked = false)
        {
            server.CloseConnection(connection);

            Player removedPlayer = null;

            if (ID == -1)
            {
                foreach (Player player in players)
                {
                    if (player != null && player.connection == connection)
                    {
                        removedPlayer = player;
                        break;
                    }
                }
            }
            else
            {
                removedPlayer = players[ID];
            }

            if (removedPlayer != null)
            {
                if (!kicked)
                {
                    Console.WriteLine("Client disconnected - ID: " + removedPlayer.playerID);
                }
                foreach (Player player in players)
                {
                    if (player != null && player != removedPlayer)
                    {
                        server.SendMessageToConnection(player.connection, new byte[] { (byte)OpCode.Disconnect, removedPlayer.playerID }, SendFlags.Reliable | SendFlags.NoNagle);
                    }
                }
                players[removedPlayer.playerID] = null;
            }
        }
Exemple #5
0
		public void Update() {
			FrameWatch.Restart();

			recentTimeSinceStartup = Time.realtimeSinceStartup;

			if (networkMessageQueue != null) {
				GC.KeepAlive(networkMessageQueue);
				GC.KeepAlive(CompressedSounds);
				GC.KeepAlive(DecompressedSounds);
				GC.KeepAlive(CompressedAnimations);
				GC.KeepAlive(DecompressedAnimations);
			}

			if (GameStateMachine.Instance.CurrentState.GetType().Equals(typeof(PauseState))) {
				if (GameStateMachine.Instance.CurrentState.CanDoTransitionTo(typeof(ChallengeSelectionState))) {
					Type[] allowedTransitions = null;
					Type objectDropperState = AccessTools.TypeByName("ObjectDropperState");

					if (MultiplayerUtils.serverMapDictionary.Count == 0) {
						allowedTransitions = objectDropperState == null ? new Type[4] : new Type[5];
						allowedTransitions[3] = typeof(LevelSelectionState);
					} else {
						allowedTransitions = objectDropperState == null ? new Type[3] : new Type[4];
					}
					allowedTransitions[0] = typeof(PlayState);
					allowedTransitions[1] = typeof(ReplayMenuState);
					allowedTransitions[2] = typeof(SettingsState);

					if (objectDropperState != null) allowedTransitions[allowedTransitions.Length - 1] = objectDropperState;

					Traverse.Create(GameStateMachine.Instance.CurrentState).Field("availableTransitions").SetValue( allowedTransitions );
				}
			}
			
			if (initiatingServerConnection) {
				ConnectionCallback();
				this.StartCoroutine(this.playerController.EncodeTextures());
				initiatingServerConnection = false;
			} else if (initiatingFileServerConnection) {
				this.debugWriter.WriteLine("connected on file server");

				byte[] connectMessage = new byte[5];
				connectMessage[0] = (byte)OpCode.Connect;
				Array.Copy(BitConverter.GetBytes(serverConnectionNumber), 0, connectMessage, 1, 4);

				fileClient.SendMessageToConnection(fileConnection, connectMessage, SendFlags.Reliable | SendFlags.NoNagle);
				isFileConnected = true;
				initiatingFileServerConnection = false;
			}

			if (closedByPeer) {
				//Client disconnected from server
				this.debugWriter.WriteLine("Disconnected from server");
				Main.utilityMenu.SendImportantChat("<b><color=\"red\">You have been disconnected from the server</color></b>", 7500);
				DisconnectFromServer();
			}

			if (problemDetectedLocally) {
				//Client unable to connect
				this.debugWriter.WriteLine("Unable to connect to server");
				Main.utilityMenu.SendImportantChat("<b><color=\"red\">You could not connect to the server</color></b>", 7500);
				DisconnectFromServer();
			}

			if (client == null) return;

			if (usernameMessage != null) {
				SendBytes(OpCode.Settings, usernameMessage, true, true);
				usernameMessage = null;
			}

			if (GameStateMachine.Instance.CurrentState.GetType() != typeof(ReplayState)) {
				if (replayStarted) {
					foreach (MultiplayerRemotePlayerController controller in remoteControllers) {
						if (controller.playerID == 255) {
							controller.skater.SetActive(false);
							controller.board.SetActive(false);
						}

						controller.EndReplay();

						foreach (ReplayAudioEventPlayer replayAudioPlayer in controller.replayController.AudioEventPlayers) {
							if (replayAudioPlayer != null) {
								Traverse.Create(replayAudioPlayer).Method("UnloadEvents").GetValue();
							}
						}
					}
				}
				replayStarted = false;
			} else {
				if (!replayStarted) {
					replayStarted = true;

					foreach (MultiplayerRemotePlayerController controller in remoteControllers) {
						if (controller.playerID == 255) {
							controller.skater.SetActive(true);
							controller.board.SetActive(true);
						}

						controller.PrepareReplay();
					}
				}
			}

			recentTimeSinceStartup = Time.realtimeSinceStartup;

			StateManagementTime = FrameWatch.Elapsed.TotalMilliseconds;
			
			if (sendingUpdates) {
				this.playerController.SendTextures();

				timeSinceLastUpdate += Time.unscaledDeltaTime;
				if (timeSinceLastUpdate > 1f / (float)tickRate) {
					SendUpdate();
					timeSinceLastUpdate = 0.0f;
				}
			}

			recentTimeSinceStartup = Time.realtimeSinceStartup;

			// Calculate network statistics every 10 seconds
			if (Time.time - statisticsResetTime > 10f && pingTimes.Count > 0 && sentAlive10Seconds > 0) {
				float totalPing = 0;
				foreach (float ping in pingTimes) {
					totalPing += ping;
				}

				int realPing = (int)(totalPing / pingTimes.Count * 1000f);
				float lossPercent = Mathf.Max(((1f - ((float)receivedAlive10Seconds / (float)sentAlive10Seconds)) * 100f), 0);

				string netstats = $"Ping: {realPing}ms           Packet Loss: {lossPercent.ToString("N2")}%";

				this.debugWriter.WriteLine(netstats);

				statisticsResetTime = Time.time;
				sentAlive10Seconds = 0;
				receivedAlive10Seconds = 0;
				pingTimes.Clear();
			}

			NetworkDiagnosticTime = FrameWatch.Elapsed.TotalMilliseconds - StateManagementTime;
			
			ProcessMessageQueue();

			MessageQueueTime = FrameWatch.Elapsed.TotalMilliseconds - NetworkDiagnosticTime;

			ProcessSoundAnimationQueue();

			double SoundAnimationTime = FrameWatch.Elapsed.TotalMilliseconds - MessageQueueTime;

			recentTimeSinceStartup = Time.realtimeSinceStartup;

			// Lerp frames using frame buffer
			List<MultiplayerRemotePlayerController> controllerToRemove = new List<MultiplayerRemotePlayerController>();

			foreach (MultiplayerRemotePlayerController controller in this.remoteControllers) {
				if (controller != null) {
					controller.ApplyTextures();
					
					if (replayStarted && GameManagement.GameStateMachine.Instance.CurrentState.GetType() == typeof(GameManagement.ReplayState)) {
						controller.replayController.TimeScale = ReplayEditorController.Instance.playbackController.TimeScale;
						controller.replayController.SetPlaybackTime(ReplayEditorController.Instance.playbackController.CurrentTime);

						if (controller.playerID == 255 && ((controller.replayController.ClipFrames.Last().time < ReplayEditorController.Instance.playbackController.CurrentTime && controller.skater.activeSelf) || (controller.replayController.ClipFrames.Count == 0 && controller.skater.activeSelf))) {
							controller.skater.SetActive(false);
							controller.board.SetActive(false);
						} else if (controller.playerID == 255 && controller.replayController.ClipFrames.Count > 0 && controller.replayController.ClipFrames.Last().time > ReplayEditorController.Instance.playbackController.CurrentTime && !controller.skater.activeSelf) {
							controller.skater.SetActive(true);
							controller.board.SetActive(true);
						}
					} 

					if (controller.playerID == 255 && (ReplayRecorder.Instance.RecordedFrames.Count < 1 || controller.replayAnimationFrames.LastOrDefault(obj => obj.realFrameTime != -1f) == null || (controller.replayAnimationFrames.Last(obj => obj.realFrameTime != -1f).realFrameTime < ReplayRecorder.Instance.RecordedFrames.First().time))) {
						controllerToRemove.Add(controller);
					}

					// TODO: Perform calculations on seperate thread and then apply transformations on main thread
					if (controller.playerID != 255)
						controller.StartFrameLerp();
				}
				recentTimeSinceStartup = Time.realtimeSinceStartup;
			}

			foreach (MultiplayerRemotePlayerController player in controllerToRemove)
				RemovePlayer(player);

			foreach (MultiplayerRemotePlayerController controller in this.remoteControllers) {
				if (controller.playerID != 255)
					controller.EndLerpFrame();
			}
			SoundAndAnimationTime = FrameWatch.Elapsed.TotalMilliseconds - MessageQueueTime;

			//private double StateManagementTime = 0;
			//private double NetworkDiagnosticTime = 0;
			//private double MessageQueueTime = 0;
			//private double SoundAndAnimationTime = 0;

			FrameWatch.Stop();
			previousQueueTimes.Add(MessageQueueTime);

			double averageTime = 0;
			if(previousQueueTimes.Count > 100) {
				previousQueueTimes.RemoveAt(previousQueueTimes.Count - 1);
				foreach(double t in previousQueueTimes) {
					averageTime += t;
				}

				averageTime /= previousQueueTimes.Count;

				if(MessageQueueTime > averageTime * 1.5) {
					this.debugWriter.WriteLine($"Frame Time Multiplayer: {FrameWatch.Elapsed.TotalMilliseconds} - Sound and Animation Queue Processing {SoundAndAnimationTime}, State management {StateManagementTime}, Network Diagnostics {NetworkDiagnosticTime}, Message Queue Processing {MessageQueueTime}, Sound and Animations {SoundAndAnimationTime}, Messages Processed {messagesProcessed}");
					foreach(Tuple<double, OpCode> item in proccessedMessages) {
						this.debugWriter.WriteLine($"Opcode {item.Item2} took {item.Item1}ms");
					}
				}
			}

			recentTimeSinceStartup = Time.realtimeSinceStartup;
		}
Exemple #6
0
        public static void ServerLoop()
        {
            Library.Initialize();

            server = new NetworkingSockets();
            Address address = new Address();

            NetworkingUtils utils = new NetworkingUtils();

            utils.SetDebugCallback(DebugType.Important, (type, message) => {
                Console.WriteLine("Valve Debug - Type: {0}, Message: {1}", type, message);
            });

            unsafe {
                int sendRateMin    = 5 * 1024 * 1024;
                int sendRateMax    = MAX_UPLOAD;
                int sendBufferSize = MAX_BUFFER;
                utils.SetConfigurationValue(ConfigurationValue.SendRateMin, ConfigurationScope.Global, IntPtr.Zero, ConfigurationDataType.Int32, new IntPtr(&sendRateMin));
                utils.SetConfigurationValue(ConfigurationValue.SendRateMax, ConfigurationScope.Global, IntPtr.Zero, ConfigurationDataType.Int32, new IntPtr(&sendRateMax));
                utils.SetConfigurationValue(ConfigurationValue.SendBufferSize, ConfigurationScope.Global, IntPtr.Zero, ConfigurationDataType.Int32, new IntPtr(&sendBufferSize));
            }

            address.SetAddress("::0", port);

            uint listenSocket = server.CreateListenSocket(ref address);
            uint pollGroup    = server.CreatePollGroup();

            Console.WriteLine($"Server {SERVER_NAME} started Listening on port {port} for maximum of {MAX_PLAYERS} players\nEnforcing maps is {ENFORCE_MAPS}");

            StartAnnouncing();

            StatusCallback status = (ref StatusInfo info, IntPtr context) => {
                switch (info.connectionInfo.state)
                {
                case ConnectionState.None:
                    break;

                case ConnectionState.Connecting:
                    server.AcceptConnection(info.connection);
                    server.SetConnectionPollGroup(pollGroup, info.connection);
                    break;

                case ConnectionState.Connected:
                    Console.WriteLine("Client connected - IP: " + info.connectionInfo.address.GetIP());

                    bool openSlot = false;

                    for (byte i = 0; i < MAX_PLAYERS; i++)
                    {
                        if (players[i] == null)
                        {
                            players[i] = new Player(i, info.connection, info.connectionInfo.address);

                            byte[] versionNumber  = ASCIIEncoding.ASCII.GetBytes(VERSION_NUMBER);
                            byte[] versionMessage = new byte[versionNumber.Length + 1];

                            versionMessage[0] = (byte)OpCode.VersionNumber;
                            Array.Copy(versionNumber, 0, versionMessage, 1, versionNumber.Length);
                            server.SendMessageToConnection(players[i].connection, versionMessage, SendFlags.Reliable | SendFlags.NoNagle);

                            if (ENFORCE_MAPS)
                            {
                                server.SendMessageToConnection(players[i].connection, mapListBytes, SendFlags.Reliable);
                                server.SendMessageToConnection(players[i].connection, GetCurrentMapHashMessage(), SendFlags.Reliable);
                            }

                            foreach (Player player in players)
                            {
                                if (player != null && player != players[i])
                                {
                                    server.SendMessageToConnection(players[i].connection, new byte[] { (byte)OpCode.Connect, player.playerID }, SendFlags.Reliable);
                                    server.SendMessageToConnection(player.connection, new byte[] { (byte)OpCode.Connect, i }, SendFlags.Reliable);

                                    if (player.usernameMessage != null)
                                    {
                                        server.SendMessageToConnection(players[i].connection, player.usernameMessage, SendFlags.Reliable);
                                    }
                                    if (player.allGearUploaded)
                                    {
                                        foreach (KeyValuePair <string, byte[]> value in player.gear)
                                        {
                                            server.SendMessageToConnection(players[i].connection, value.Value, SendFlags.Reliable);
                                        }
                                    }
                                }
                            }

                            server.FlushMessagesOnConnection(players[i].connection);

                            openSlot = true;
                            break;
                        }
                    }

                    if (!openSlot)
                    {
                        server.CloseConnection(info.connection);
                    }
                    break;

                case ConnectionState.ClosedByPeer:
                    RemovePlayer(info.connection);
                    break;
                }
            };

#if VALVESOCKETS_SPAN
            MessageCallback messageCallback = (in NetworkingMessage netMessage) => {
                byte[] messageData = new byte[netMessage.length];
                netMessage.CopyTo(messageData);

                Player sendingPlayer = null;
                foreach (Player player in players)
                {
                    if (player != null && player.connection == netMessage.connection)
                    {
                        sendingPlayer = player;
                        break;
                    }
                }

                if (sendingPlayer != null)
                {
                    ProcessMessage(messageData, sendingPlayer.playerID, server);
                }
            };
#else
            const int maxMessages = 256;

            NetworkingMessage[] netMessages = new NetworkingMessage[maxMessages];
#endif
            while (RUNNING)
            {
                server.DispatchCallback(status);

#if VALVESOCKETS_SPAN
                server.ReceiveMessagesOnPollGroup(pollGroup, messageCallback, 256);
#else
                int netMessagesCount = server.ReceiveMessagesOnConnection(listenSocket, netMessages, maxMessages);

                if (netMessagesCount > 0)
                {
                    for (int i = 0; i < netMessagesCount; i++)
                    {
                        ref NetworkingMessage netMessage = ref netMessages[i];

                        byte[] messageData = new byte[netMessage.length];
                        netMessage.CopyTo(messageData);

                        Player sendingPlayer = null;
                        foreach (Player player in players)
                        {
                            if (player != null && player.connection == netMessage.connection)
                            {
                                sendingPlayer = player;
                                break;
                            }
                        }

                        //Console.WriteLine("Recieved packet from connection {0}, sending player null: {1}", netMessage.connection, sendingPlayer == null);

                        if (sendingPlayer != null)
                        {
                            ProcessMessage(messageData, sendingPlayer.playerID, server);
                        }

                        netMessage.Destroy();
                    }
                }
#endif

                mapVotes.Clear();
                total_players = 0;
                foreach (Player player in players)
                {
                    if (player != null)
                    {
                        total_players++;

                        if (player.timeoutWatch.ElapsedMilliseconds > 15000)
                        {
                            Console.WriteLine($"{player.playerID} has been timed out for not responding for 15 seconds");

                            RemovePlayer(player.connection, player.playerID, true);
                        }

                        if (!mapVotes.ContainsKey(player.currentVote))
                        {
                            mapVotes.Add(player.currentVote, 1);
                        }
                        else
                        {
                            mapVotes[player.currentVote]++;
                        }
                    }
                }

                // Handle map voting and map enforcement
                if (ENFORCE_MAPS)
                {
                    if (total_players == 0)
                    {
                        currentMapHash = "1";
                    }

                    bool startNewTimer = false;
                    if (mapVotes.ContainsKey("current"))
                    {
                        if (mapVotes["current"] < (int)Math.Ceiling((float)total_players / 2))
                        {
                            if (!mapVoteTimer.IsRunning)
                            {
                                startNewTimer = true;
                            }
                        }
                    }
                    else if (!mapVoteTimer.IsRunning && total_players > 0)
                    {
                        startNewTimer = true;
                    }

                    if (startNewTimer)
                    {
                        mapVoteTimer.Restart();

                        byte[] mapVoteMsg = new byte[] { (byte)OpCode.MapVote, 0, 0 };

                        foreach (Player player in players)
                        {
                            if (player != null)
                            {
                                server.SendMessageToConnection(player.connection, mapVoteMsg, SendFlags.Reliable);
                            }
                        }
                    }

                    if (mapVoteTimer.IsRunning && mapVoteTimer.ElapsedMilliseconds > 30000 && total_players > 0)
                    {
                        mapVoteTimer.Stop();

                        Tuple <string, int> mostVoted = null;

                        foreach (var item in mapVotes)
                        {
                            if (!item.Key.Equals("current"))
                            {
                                if (mostVoted == null || mostVoted.Item2 < item.Value)
                                {
                                    mostVoted = Tuple.Create <string, int>(item.Key, item.Value);
                                }
                            }
                        }

                        currentMapHash = mostVoted.Item1;

                        byte[] newMapMessage = GetCurrentMapHashMessage();

                        foreach (Player player in players)
                        {
                            if (player != null)
                            {
                                server.SendMessageToConnection(player.connection, newMapMessage, SendFlags.Reliable);

                                player.currentVote = "current";
                            }
                        }
                    }
                    else if (total_players == 0)
                    {
                        mapVoteTimer.Stop();
                    }
                }
            }
Exemple #7
0
        private static void ProcessMessage(byte[] buffer, byte fromID, NetworkingSockets server)
        {
            if (!Enum.IsDefined(typeof(OpCode), (OpCode)buffer[0]) || players[fromID] == null)
            {
                return;
            }

            players[fromID].timeoutWatch.Restart();

            switch ((OpCode)buffer[0])
            {
            case OpCode.Settings:
                Thread usernameThread = new Thread(new ParameterizedThreadStart(Server.HandleUsername));
                usernameThread.IsBackground = true;
                usernameThread.Start(Tuple.Create(buffer, fromID));
                break;

            case OpCode.Texture: {
                Console.WriteLine("Received Texture from " + fromID);
                Player player = players[fromID];
                if (player != null && player.playerID == fromID)
                {
                    player.AddGear(buffer);
                    if (player.allGearUploaded)
                    {
                        foreach (Player player2 in players)
                        {
                            if (player2 != null && player2.playerID != fromID)
                            {
                                foreach (KeyValuePair <string, byte[]> value in player.gear)
                                {
                                    server.SendMessageToConnection(player2.connection, value.Value, SendFlags.Reliable);
                                }
                                server.FlushMessagesOnConnection(player2.connection);
                            }
                        }
                    }
                }
            }
            break;

            case OpCode.Animation:
                if (players[fromID] != null)
                {
                    bool reliable = buffer[buffer.Length - 1] == (byte)1 ? true : false;
                    buffer[buffer.Length - 1] = fromID;

                    foreach (Player player in players)
                    {
                        if (player != null && player.playerID != fromID)
                        {
                            ConnectionStatus status = new ConnectionStatus();
                            if (server.GetQuickConnectionStatus(player.connection, ref status))
                            {
                                int bytesPending = status.pendingReliable + status.sentUnackedReliable;

                                if (reliable && bytesPending >= MAX_BYTES_PENDING)
                                {
                                    Console.WriteLine($"Sending animation unreliably to ({player.playerID}) because pending bytes is higher than max");
                                    reliable = false;
                                }
                            }

                            server.SendMessageToConnection(player.connection, buffer, reliable ? SendFlags.Reliable | SendFlags.NoNagle : SendFlags.Unreliable | SendFlags.NoNagle);
                        }
                    }
                }
                break;

            case OpCode.Chat:
                string contents = ASCIIEncoding.ASCII.GetString(buffer, 1, buffer.Length - 1);
                Console.WriteLine("Chat Message from {0} saying: {1}", fromID, contents);

                byte[] sendBuffer = new byte[buffer.Length + 1];
                Array.Copy(buffer, 0, sendBuffer, 0, buffer.Length);
                sendBuffer[buffer.Length] = fromID;

                foreach (Player player in players)
                {
                    if (player != null)
                    {
                        server.SendMessageToConnection(player.connection, sendBuffer, SendFlags.Reliable);
                    }
                }
                break;

            case OpCode.MapVote:
                if (ENFORCE_MAPS)
                {
                    string vote = ASCIIEncoding.ASCII.GetString(buffer, 1, buffer.Length - 1);

                    if (mapList.ContainsKey(vote) || vote.ToLower().Equals("current"))
                    {
                        vote = mapList.ContainsKey(vote) && mapList[vote].Equals(currentMapHash) ? "current" : vote;
                        players[fromID].currentVote = vote;

                        Console.WriteLine("{0} voted for the map {1}", fromID, mapList.ContainsKey(vote) ? mapList[vote] : vote);
                    }
                }
                break;

            case OpCode.StillAlive:
                if (players[fromID] != null)
                {
                    server.SendMessageToConnection(players[fromID].connection, buffer, SendFlags.Unreliable | SendFlags.NoNagle);
                }
                break;
            }
        }
Exemple #8
0
 public void SendTo(UInt32 connectionID, byte[] data, SendFlags flags)
 {
     server.SendMessageToConnection(connectionID, data, flags);
 }
Exemple #9
0
 void Test()
 {
     byte[] data = new byte[64];
     client.SendMessageToConnection(connection, data);
 }
Exemple #10
0
        public void ServerLoop()
        {
            Library.Initialize();

            server = new NetworkingSockets();
            Address address = new Address();

            //Console.WriteLine($"Gameplay port: {Server.port}, File Server Port: {(ushort)(Server.port + 1)}");

            address.SetAddress("::0", (ushort)(Server.port + 1));

            listenSocket = server.CreateListenSocket(ref address);
            pollGroup    = server.CreatePollGroup();

            NetworkingUtils utils = new NetworkingUtils();

            unsafe {
                int sendRateMin = 512000;
                int sendRateMax = Server.FILE_MAX_UPLOAD;
                utils.SetConfigurationValue(ConfigurationValue.SendRateMin, ConfigurationScope.ListenSocket, new IntPtr(listenSocket), ConfigurationDataType.Int32, new IntPtr(&sendRateMin));
                utils.SetConfigurationValue(ConfigurationValue.SendRateMax, ConfigurationScope.ListenSocket, new IntPtr(listenSocket), ConfigurationDataType.Int32, new IntPtr(&sendRateMax));
            }
            StatusCallback status = StatusCallbackFunction;

            MessageCallback messageCallback = (in NetworkingMessage netMessage) => {
                byte[] message = new byte[netMessage.length];
                netMessage.CopyTo(message);

                if ((OpCode)message[0] == OpCode.Connect)
                {
                    uint originalConnection = BitConverter.ToUInt32(message, 1);

                    Player newPlayer = null;
                    foreach (Player player in mainServer.players)
                    {
                        if (player != null && player.connection == originalConnection)
                        {
                            player.fileConnection = netMessage.connection;
                            newPlayer             = player;
                            break;
                        }
                    }

                    if (newPlayer == null)
                    {
                        //Console.WriteLine("Connection on file server doesn't exist on gameplay server");

                        server.CloseConnection(netMessage.connection);
                    }
                    else
                    {
                        foreach (Player player in mainServer.players)
                        {
                            if (player != null && player.playerID != newPlayer.playerID && player.completedGearStream)
                            {
                                player.SendGear(newPlayer.fileConnection, server);
                            }
                        }

                        foreach (Plugin plugin in mainServer.loadedPlugins)
                        {
                            if (plugin.hash != "" && plugin.dependencyFile != "")
                            {
                                byte[] hashBytes   = ASCIIEncoding.ASCII.GetBytes(plugin.hash);
                                byte[] hashMessage = new byte[hashBytes.Length + 2];

                                hashMessage[0] = (byte)OpCode.PluginHash;
                                hashMessage[1] = plugin.pluginID;
                                Array.Copy(hashBytes, 0, hashMessage, 2, hashBytes.Length);

                                server.SendMessageToConnection(newPlayer.fileConnection, hashMessage, SendFlags.Reliable);
                            }
                        }
                    }
                }
                else if ((OpCode)message[0] == OpCode.StillAlive)
                {
                    server.SendMessageToConnection(netMessage.connection, message, SendFlags.Unreliable | SendFlags.NoNagle);
                }
                else
                {
                    foreach (Player player in mainServer.players)
                    {
                        if (player != null && player.fileConnection == netMessage.connection)
                        {
                            mainServer.ProcessMessage(message, player.playerID, mainServer.server);
                        }
                    }
                }
            };

            Stopwatch fileServerLoopTime = new Stopwatch();

            while (mainServer.RUNNING)
            {
                fileServerLoopTime.Restart();
                server.DispatchCallback(status);

                server.ReceiveMessagesOnPollGroup(pollGroup, messageCallback, 256);
                SpinWait.SpinUntil(() => fileServerLoopTime.Elapsed.TotalMilliseconds >= 1, 1);
            }
        }
Exemple #11
0
        public void ServerLoop()
        {
            Library.Initialize();

            server = new NetworkingSockets();
            Address address = new Address();

            //Console.WriteLine($"Gameplay port: {Server.port}, File Server Port: {(ushort)(Server.port + 1)}");

            address.SetAddress("::0", (ushort)(Server.port + 1));

            listenSocket = server.CreateListenSocket(ref address);
            pollGroup    = server.CreatePollGroup();

            NetworkingUtils utils = new NetworkingUtils();

            unsafe {
                int sendRateMin = 512000;
                int sendRateMax = Server.FILE_MAX_UPLOAD;
                utils.SetConfigurationValue(ConfigurationValue.SendRateMin, ConfigurationScope.ListenSocket, new IntPtr(listenSocket), ConfigurationDataType.Int32, new IntPtr(&sendRateMin));
                utils.SetConfigurationValue(ConfigurationValue.SendRateMax, ConfigurationScope.ListenSocket, new IntPtr(listenSocket), ConfigurationDataType.Int32, new IntPtr(&sendRateMax));
            }
            StatusCallback status = StatusCallbackFunction;

            MessageCallback messageCallback = (in NetworkingMessage netMessage) => {
                byte[] message = new byte[netMessage.length];
                netMessage.CopyTo(message);

                if ((OpCode)message[0] == OpCode.Connect)
                {
                    uint originalConnection = BitConverter.ToUInt32(message, 1);

                    Player newPlayer = null;
                    foreach (Player player in mainServer.players)
                    {
                        if (player != null && player.connection == originalConnection)
                        {
                            player.fileConnection = netMessage.connection;
                            newPlayer             = player;
                            break;
                        }
                    }

                    if (newPlayer == null)
                    {
                        //Console.WriteLine("Connection on file server doesn't exist on gameplay server");

                        server.CloseConnection(netMessage.connection);
                    }
                    else
                    {
                        foreach (Player player in mainServer.players)
                        {
                            if (player != null && player.playerID != newPlayer.playerID && player.completedGearStream)
                            {
                                player.SendGear(newPlayer.fileConnection, server);
                            }
                        }
                    }
                }
                else if ((OpCode)message[0] == OpCode.StillAlive)
                {
                    server.SendMessageToConnection(netMessage.connection, message, SendFlags.Unreliable | SendFlags.NoNagle);
                }
                else
                {
                    foreach (Player player in mainServer.players)
                    {
                        if (player != null && player.fileConnection == netMessage.connection)
                        {
                            mainServer.ProcessMessage(message, player.playerID, mainServer.server);
                        }
                    }
                }
            };

            while (mainServer.RUNNING)
            {
                server.DispatchCallback(status);

                server.ReceiveMessagesOnPollGroup(pollGroup, messageCallback, 256);
            }
        }
Exemple #12
0
        public void StatusCallbackFunction(ref StatusInfo info, IntPtr context)
        {
            switch (info.connectionInfo.state)
            {
            case ConnectionState.None:
                break;

            case ConnectionState.Connecting: {
                if (info.connectionInfo.listenSocket != listenSocket)
                {
                    mainServer.StatusCallbackFunction(ref info, context);
                    break;
                }

                //Console.WriteLine("connecting on file server");

                if (mainServer.bannedIPs.Contains(info.connectionInfo.address.GetIP()))
                {
                    //Console.WriteLine("Ban player attempted to connect to the server, IP: {0}", info.connectionInfo.address.GetIP());
                    server.CloseConnection(info.connection);
                }
                else
                {
                    server.AcceptConnection(info.connection);
                    server.SetConnectionPollGroup(pollGroup, info.connection);
                }
            } break;

            case ConnectionState.Connected: {
                if (info.connectionInfo.listenSocket != listenSocket)
                {
                    mainServer.StatusCallbackFunction(ref info, context);
                    break;
                }

                if (mainServer.motdBytes != null)
                {
                    server.SendMessageToConnection(info.connection, mainServer.motdBytes);
                }

                foreach (Player player in mainServer.players)
                {
                    foreach (Plugin plugin in mainServer.loadedPlugins)
                    {
                        if (plugin.hash != "")
                        {
                            byte[] hashBytes   = ASCIIEncoding.ASCII.GetBytes(plugin.hash);
                            byte[] hashMessage = new byte[hashBytes.Length + 2];

                            hashMessage[0] = (byte)OpCode.PluginHash;
                            hashMessage[1] = plugin.pluginID;
                            Array.Copy(hashBytes, 0, hashMessage, 2, hashBytes.Length);

                            server.SendMessageToConnection(player.connection, hashMessage, SendFlags.Reliable);
                        }
                    }
                }

                //Console.WriteLine("connected on file server");
            } break;

            case ConnectionState.ClosedByPeer:
            case ConnectionState.ProblemDetectedLocally:
                mainServer.RemovePlayer(info.connection);
                break;
            }
        }