/// <summary> /// Removes the current Player from its Team /// </summary> /// <param name="player">Player to remove</param> private void RemovePlayer(Player player) { // Little verification : we ask the user to validate his action if (Choice_Prefabs.CHOICE_REMOVEPLAYER.GetChoice() == 0) { // Asking to remove the Player Instructions instruction = Instructions.Team_RemovePlayer; Net.COMMUNICATION.Send(comm.GetStream(), new Communication(instruction, player)); // We receive whether it work or not if (Net.BOOL.Receive(comm.GetStream())) { // We remove the Player from its Team player.team.players.Remove(player); // We display a message accordingly CONSOLE.WriteLine(ConsoleColor.Green, "Player " + player.name + " removed !"); } else { // We display a message accordingly CONSOLE.WriteLine(ConsoleColor.Red, "Player " + player.name + "was not removed..."); } CONSOLE.WaitForInput(); } }
/// <summary> /// Sends a Coach of which we know the id /// </summary> /// <param name="id">Id of the Coach we seek</param> public void GetCoachById(Guid id) { // Writing a Log in the Console CONSOLE.WriteLine(ConsoleColor.Yellow, "Coach's id : " + id); // We send the default Coach if no match was found / the correct one if a match was found Net.COACH.Send(comm.GetStream(), Database.COACH.GetById(id)); }
/// <summary> /// Sends a Coach of which we know the name /// </summary> /// <param name="name">name of the Coach we seek</param> public void GetCoachByName(string name) { // Writing a Log in the Console CONSOLE.WriteLine(ConsoleColor.Yellow, "Coach's name : " + name); // We send the default Coach if no match was found / the correct one if a match was found Net.COACH.Send(comm.GetStream(), Database.COACH.GetByName(name)); }
/// <summary> /// When a Client logs off /// </summary> /// <param name="communication"> communication Logged Off </param> private void LogOut(TcpClient communication) { // A client has logged off, but is still present CONSOLE.WriteLine(ConsoleColor.Red, "Logged Out @" + communication); cptCoachessLoggedIn--; DisplaySituation(); }
/// <summary> /// When a Coach logs in /// </summary> /// <param name="communication"> communication Logged in </param> private void LogIn(TcpClient communication) { // A client has logged in CONSOLE.WriteLine(ConsoleColor.Green, "Logged In @" + communication); cptCoachessLoggedIn++; DisplaySituation(); }
public void Start() { Console.Write(" Server launched !\n\n"); // We create and initialize a Listener TcpListener listener = new TcpListener(new IPAddress(new byte[] { 127, 0, 0, 1 }), port); listener.Start(); cptCoachessLoggedIn = 0; receivers = new List <Receiver>(); // Filling the database // Database.FillDatabase(); while (true) { // Coucou, j'écoute si un Client se connecte TcpClient comm = listener.AcceptTcpClient(); // Oh tiens, un client s'est connecté CONSOLE.WriteLine(ConsoleColor.DarkGreen, "Connection established @" + comm); // Je récupère ses infos... Receiver receiver = new Receiver(this, comm); // ... J'initialise quelques events... receiver.When_Server_Exit += EndingCommunication; receiver.When_Server_LogIn += LogIn; receiver.When_Server_LogOff += LogOut; receiver.When_Coach_Create += CoachCreate; receiver.When_Team_Create += TeamCreate; receiver.When_Player_Create += PlayerCreate; receiver.When_Player_Remove += PlayerRemove; receiver.When_Player_LevelsUp += PlayerLevelsUp; // ... et je lance une connexion avec le serveur new Thread(receiver.DoOperation).Start(); // Je garde la connexion en mémoire dans une Liste de Receiver receivers.Add(receiver); // On affiche les informations dans la console DisplaySituation(); // Et hop, je retourne écouter si un Client se connecte... } }
/// <summary> /// Ensures the user Logs Out of the Softare (but remains to the Log In / Sign In menu) /// </summary> private void LogOut() { // Display a Farewell message CONSOLE.WriteLine(ConsoleColor.Blue, "\n\n Goodbye ! We hope to see you soon :)\n\n"); // Resetting the user's Data : no user is logged in anymore userData = new Coach(); // Warning the server we log out Instructions instruction = Instructions.LogOut; Object content = null; Net.COMMUNICATION.Send(comm.GetStream(), new Communication(instruction, content)); }
/// <summary> /// A panel saying goodbye to the user /// </summary> private void PanelExitSoftware() { // Displaying a farewell message Console.Clear(); CONSOLE.WriteLine(ConsoleColor.Blue, "\n\n\n Goodbye !! We hope to see you soon :)"); // Warning the server we leave the software Instructions instruction = Instructions.Exit_Software; Object content = null; Net.COMMUNICATION.Send(comm.GetStream(), new Communication(instruction, content)); // Environment.Exit(0); }
/// <summary> /// A panel displaying all options a user can perform while logged to the program (Topic / Chat) /// </summary> private void PanelConnected() { bool continuingConnection = true; while (continuingConnection) { int choice = Choice_Prefabs.CHOICE_CONNECTED.GetChoice(); switch (choice) { // COACH case 0: DisplayCoach(userData); break; // LEAGUE case 1: CONSOLE.WriteLine(ConsoleColor.Magenta, "Not yet implemented !"); break; case 2: CONSOLE.WriteLine(ConsoleColor.Magenta, "Not yet implemented !"); break; // TEAM case 3: PanelTeams(); break; case 4: NewTeam(); break; // LOG OUT case 5: LogOut(); continuingConnection = false; break; default: Console.WriteLine("Error at the Main menu"); break; } CONSOLE.WaitForInput(); } }
/// <summary> /// When a Client stops the communication with the server /// </summary> /// <param name="communication"></param> private void EndingCommunication(TcpClient communication) { // A client has disconnected the software CONSOLE.WriteLine(ConsoleColor.DarkRed, "Connection stopped @" + communication); // We remove the Receiver communication from our list foreach (Receiver receiver in receivers) { if (receiver.comm == communication) { receivers.Remove(receiver); break; } } DisplaySituation(); }
/// <summary> /// Gets the newly created Coach's data of the user, and connects him / makes him retry accordingly /// </summary> private void SignIn() { bool continueSignin = true; string errorMessage = ""; while (continueSignin) { // Displaying some messages Console.Clear(); CONSOLE.WriteLine(ConsoleColor.Blue, "\n Enter empty fields to leave the SIGN-IN"); // Displays a message if the credentials are incorrect CONSOLE.WriteLine(ConsoleColor.Red, errorMessage); // USERNAME Console.Write("\n Please enter your username : "******"\n Please enter your password : "******"\n Please verify your password : "******"\n Please enter your email : "); string email = Console.ReadLine(); // All the fields are empty : go back to the menu if (name.Length == 0 && password.Length == 0 && passwordVerif.Length == 0 && email.Length == 0) { continueSignin = false; } // If at least one field is empty : ERROR else if (name.Length == 0 || password.Length == 0 || passwordVerif.Length == 0 || email.Length == 0) { errorMessage = PrefabMessages.INCOMPLETE_FIELDS; } // The password and its verification do not match : ERROR else if (password != passwordVerif) { errorMessage = PrefabMessages.SIGNIN_PASSWORD_DONT_MATCH; } // NOW, we don't have to verify the PasswordVerif field anymore ! // If at least one field is too long : ERROR else if (name.Length > PrefabMessages.INPUT_MAXSIZE_COACH_NAME || password.Length > PrefabMessages.INPUT_MAXSIZE_COACH_PASSWORD || email.Length > PrefabMessages.INPUT_MAXSIZE_COACH_EMAIL) { errorMessage = PrefabMessages.INCORRECT_INPUT_SIZE; } // If at least one field has one incorrect character : ERROR else if (!Util.CorrectInput(name) || !Util.CorrectInput(password) || !Util.CorrectInput(email)) { errorMessage = PrefabMessages.INCORRECT_INPUT_CHARACTER; } // Otherwise : verify with the server else { // Sending the new Coach (with password !) Instructions instruction = Instructions.SignIn; Object content = new CoachWithPassword(name, password, email); Net.COMMUNICATION.Send(comm.GetStream(), new Communication(instruction, content)); // We get the Coach data back // CORRECT : regular data // INCORRECT : default data userData = Net.COACH.Receive(comm.GetStream()); // the data is complete : successful Sign in if (userData.IsComplete) { continueSignin = false; } // If the data is incomplete : the profile's name and/or email is already taken, we reset the sign-in { errorMessage = PrefabMessages.SIGNIN_FAILURE; } } } }
// METHODS - CONNECTION /// <summary> /// Gets the Credentials of the user, and connects him / makes him retry accordingly /// </summary> private void LogIn() { bool continueLogin = true; string errorMessage = ""; do { // Displaying some messages Console.Clear(); CONSOLE.WriteLine(ConsoleColor.Blue, "\n Enter empty fields to leave the LOGIN"); // Displays a message if the credentials are incorrect CONSOLE.WriteLine(ConsoleColor.Red, errorMessage); // USERNAME Console.Write("\n Please enter your name : "); string name = Console.ReadLine(); // PASSWORD Console.Write("\n Please enter your password : "); string password = Console.ReadLine(); // All the fields are empty : go back to the menu if (name.Length == 0 && password.Length == 0) { continueLogin = false; } // If at least one field is empty : ERROR else if (name.Length == 0 || password.Length == 0) { errorMessage = PrefabMessages.INCOMPLETE_FIELDS; } // If at least one field is too long : ERROR else if (name.Length > PrefabMessages.INPUT_MAXSIZE_COACH_NAME || password.Length > PrefabMessages.INPUT_MAXSIZE_COACH_PASSWORD) { errorMessage = PrefabMessages.INCORRECT_INPUT_SIZE; } // If at least one field has one incorrect character : ERROR else if (!Util.CorrectInput(name) || !Util.CorrectInput(password)) { errorMessage = PrefabMessages.INCORRECT_INPUT_CHARACTER; } // Otherwise : verify with the server else { // Sending the credentials Instructions instruction = Instructions.LogIn; Object content = new Credentials(name, password); Net.COMMUNICATION.Send(comm.GetStream(), new Communication(instruction, content)); // Receiving the response ID userData = Net.COACH.Receive(comm.GetStream()); // Match found, we proceed forward if (userData.IsComplete) { continueLogin = false; } // If the ID is Empty : there was no match found, we reset the login else { errorMessage = PrefabMessages.LOGIN_FAILURE; } } }while (continueLogin); }
/// <summary> /// Display some data about the number of users, whether logged in just in the connection menu /// </summary> private void DisplaySituation() { CONSOLE.WriteLine(ConsoleColor.Magenta, "Number of clients Logged In / Number of clients Total : " + cptCoachessLoggedIn + "/ " + receivers.Count); }
/// <summary> /// When a Player levels up /// </summary> /// <param name="player"></param> private void PlayerLevelsUp(Player player) { // Asking to level up a Player Instructions instruction = Instructions.Player_LevelUp; Net.COMMUNICATION.Send(comm.GetStream(), new Communication(instruction, player)); // We receive / define some variables int dice1 = Net.INT.Receive(comm.GetStream()); int dice2 = Net.INT.Receive(comm.GetStream()); dice1 = 5; dice2 = 6; List <EffectType> types = EffectStuff.GetEffectTypesForLevelUp(player.role, dice1, dice2); // There are 2 steps : // PART 1 - display some useful info to the user // PART 2 - Wait for the user to choose a new Effect for his Player // PART 1 - display some useful info to the user Console.Clear(); Console.WriteLine("New level !\n\n\n\nyou rolled {0} - {1} !", dice1, dice2); Console.WriteLine("You can level up in any category :"); types.ForEach(type => Console.WriteLine(" - " + type)); CONSOLE.WaitForInput(); // PART 2 - Wait for the user to choose a new Effect for his Player // We initialize our variables List <List <Effect> > effects = EffectStuff.GetEffectsForLevelUp(types); bool continuing = true; Effect chosenEffect = effects[0][0]; int currentType = 0; int currentEffect = 0; // While the user doesn't press Enter, the loop continues do { // We clear the console, and display a given message Console.Clear(); // We display all our Types for (int t = 0; t < types.Count; t++) { // Display the current EffectType Console.WriteLine("\n" + types[t]); // Display all its Effects (with an arrow if it is the current one) for (int e = 0; e < effects[t].Count; e++) { // Initialize some variables Effect effect = effects[t][e]; string arrow = (currentType == t && currentEffect == e) ? "\t --> " : "\t "; ConsoleColor color = (player.effectsAll.Contains(effect)) ? ConsoleColor.Red : ConsoleColor.Blue; // Display the result CONSOLE.WriteLine(color, arrow + effect.name()); } } // We read the input ConsoleKeyInfo input = Console.ReadKey(); bool goToLastEffect = false; // If it is an Array key (UP or DOWN), we modify our index accordingly if (input.Key == ConsoleKey.UpArrow) { currentEffect--; // If the index goes too low, we change type if (currentEffect < 0) { currentType--; goToLastEffect = true; } } if (input.Key == ConsoleKey.DownArrow) { currentEffect++; // If the index goes too high, we change type if (currentEffect > effects[currentType].Count - 1) { currentType++; currentEffect = 0; } } // If it is a LEFT Array key : go to the previous type if (input.Key == ConsoleKey.LeftArrow) { currentType--; currentEffect = 0; } // If it is a RIGHT Array key : go to the next type if (input.Key == ConsoleKey.RightArrow) { currentType++; currentEffect = 0; } // If the type is too high / too low, we change it accordingly if (currentType < 0) { currentType = types.Count - 1; } if (currentType > types.Count - 1) { currentType = 0; } // If needed : we replace the effect counter to the last index of the current list if (goToLastEffect) { currentEffect = effects[currentType].Count - 1; } // We check if we end the loop if (input.Key == ConsoleKey.Enter) { // We set the chosen Effect chosenEffect = effects[currentType][currentEffect]; Console.Clear(); // We display a message, whether the Effect can be chosen or not if (player.effectsAll.Contains(chosenEffect)) { CONSOLE.WriteLine(ConsoleColor.Red, "You cannot choose the Effect " + chosenEffect.name() + " :\n\nyour Player already has it !!"); CONSOLE.WaitForInput(); } else { continuing = false; } } }while (continuing); // Small message CONSOLE.WriteLine(ConsoleColor.Green, "You have chosen the Effect " + chosenEffect.name() + " !!"); // Sending the chosen Effect Net.EFFECT.Send(comm.GetStream(), chosenEffect); // If the Effect was validated : add it to the Player if (Net.BOOL.Receive(comm.GetStream())) { CONSOLE.WriteLine(ConsoleColor.Green, "\n\n\tEffect validated !!"); player.effects.Add(chosenEffect); } else { CONSOLE.WriteLine(ConsoleColor.Red, "\n\n\tEffect refused..."); } CONSOLE.WaitForInput(); }
/// <summary> /// Creates a new Player /// </summary> /// <param name="team">Team the Player is in</param> private void NewPlayer(Team team) { bool continueNewPlayer = true; bool continueNewPlayerInputs = true; string errorMessage = ""; do { // CHOICE // We dynamically create a List containing all the roles names List <string> choiceString = new List <string>(); team.race.roles().ForEach(role => choiceString.Add(role.ToStringCustom())); // We add as a last choice the option to "Cancel" choiceString.Add("Cancel"); // We create the Choice Choice c = new Choice("please Select a Role (last one = cancel) : ", choiceString); int index = c.GetChoice(); if (index != choiceString.Count - 1) { // We save the Role Role role = team.race.roles()[index]; // if the role chosen is too cost-expensive if (role.price() > team.money) { CONSOLE.WriteLine(ConsoleColor.Red, PrefabMessages.NOT_ENOUGH_MONEY); CONSOLE.WaitForInput(); } // if the player can afford it : continue else { // Inputs do { Console.Clear(); // Displays a message if the credentials are incorrect CONSOLE.WriteLine(ConsoleColor.Red, errorMessage); // NAME Console.Write("\n Please enter the {0}'s name (empty = go back) : ", role.name()); string name = Console.ReadLine(); // All the fields are empty : go back to the menu if (name.Length == 0) { continueNewPlayerInputs = false; } // If at least one field is too long : ERROR else if (name.Length > PrefabMessages.INPUT_MAXSIZE_COACH_NAME) { errorMessage = PrefabMessages.INCORRECT_INPUT_SIZE; } // If at least one field has one incorrect character : ERROR else if (!Util.CorrectInput(name)) { errorMessage = PrefabMessages.INCORRECT_INPUT_CHARACTER; } // Otherwise : verify with the server else { // Sending the new Player Instructions instruction = Instructions.Team_AddPlayer; Player newPlayer = new Player(name, role, team); Net.COMMUNICATION.Send(comm.GetStream(), new Communication(instruction, newPlayer)); // We receive the id of the Player from the server Guid idReceived = Net.GUID.Receive(comm.GetStream()); // We see if the id received is valid if (idReceived != Guid.Empty) { // We set the received id newPlayer.id = idReceived; // We add the Player to the user's team team.players.Add(newPlayer); // We make the transaction (the team has less money now) team.money -= role.price(); // We display a success message CONSOLE.WriteLine(ConsoleColor.Green, PrefabMessages.PLAYER_CREATION_SUCCESS); // Ending the loops continueNewPlayerInputs = false; continueNewPlayer = false; } else { errorMessage = PrefabMessages.PLAYER_CREATION_FAILURE; } } }while (continueNewPlayerInputs); } } else { continueNewPlayer = false; } }while (continueNewPlayer); }
public int GetChoice() { // We initialize our variables bool continuing = true; int currentChoice = 0; int MIN = 0; int MAX = choices.Count - 1; // While the user doesn't press Enter, the loop continues do { // We clear the console, and display a given message Console.Clear(); CONSOLE.WriteLine(ConsoleColor.Blue, message + "\n\n"); // We display all our choices (and we highlight the current choice) int index = 0; foreach (string s in choices) { if (index == currentChoice) { Console.Write(" --> "); } else { Console.Write(" "); } // We set the color to Blue if we reach the final statement (usually one saying "Go back" or "Log out") ConsoleColor color = (index == MAX) ? ConsoleColor.Blue : ConsoleColor.White; CONSOLE.WriteLine(color, choices[index++] + "\n"); } // We read the input switch (Console.ReadKey().Key) { case ConsoleKey.UpArrow: currentChoice--; // If the value goes too low, it goes to the other extreme if (currentChoice < MIN) { currentChoice = MAX; } break; case ConsoleKey.DownArrow: currentChoice++; // If the value goes too high, it goes to the other extreme if (MAX < currentChoice) { currentChoice = MIN; } break; case ConsoleKey.LeftArrow: currentChoice = MIN; break; case ConsoleKey.RightArrow: currentChoice = MAX; break; case ConsoleKey.Enter: continuing = false; break; case ConsoleKey.Escape: continuing = false; currentChoice = MAX; break; } }while (continuing); // We return the value return(currentChoice); }
/// <summary> /// Server's HUB : it does stuff. /// </summary> public void DoOperation() { while (true) { // We receive a Communication from the client Communication communication = Net.COMMUNICATION.Receive(comm.GetStream()); // We extract the data Instructions instruction = communication.instruction; Object content = communication.content; // We display the instruction CONSOLE.WriteLine(ConsoleColor.Cyan, "\nINSTRUCTION : " + instruction); // According to the instruction, we'll do a specific action switch (instruction) { case Instructions.Exit_Software: // We raise the event : a user left the software When_Server_Exit?.Invoke(comm); break; // CREDENTIALS case Instructions.LogIn: if (LogIn((Credentials)content)) { // We raise the event : a user has logged in When_Server_LogIn?.Invoke(comm); } break; case Instructions.SignIn: // We get the profile Signed In CoachWithPassword newCoach = SignIn((CoachWithPassword)content); // If the Profile's ID is not Empty (means that the Sign In was successful) if (newCoach.id != Guid.Empty) { // We raise the event : a user has logged in When_Server_LogIn?.Invoke(comm); // We raise the event : a Profile has been created When_Coach_Create(newCoach); } break; case Instructions.LogOut: LogOut(); // We raise the event : a user has logged off When_Server_LogOff?.Invoke(comm); break; // COACH case Instructions.Coach_GetById: GetCoachById((Guid)content); break; // TEAM case Instructions.Team_New: // We get the newly created Team Team newTeam = NewTeam((Team)content); // If the Team can be created (ID is not empty) if (newTeam.IsComplete) { // We raise the event : a Team has been created When_Team_Create?.Invoke(newTeam); } break; case Instructions.Team_AddPlayer: // We get the newly created Player Player newPlayer = NewPlayer((Player)content); // If the Player can be created (ID is not empty) if (newPlayer.IsComplete) { // We raise the event : a Player has been created When_Player_Create?.Invoke(newPlayer); } break; case Instructions.Team_RemovePlayer: // We get the Player to remove Player playerToRemove = (Player)content; // We remove him from the database playerToRemove = RemovePlayer(playerToRemove); // If the removal was successful) if (playerToRemove.IsComplete) { // We raise the event : a Player has been removed When_Player_Remove?.Invoke(playerToRemove); } break; // PLAYER case Instructions.Player_LevelUp: // We get the Player to remove Player player = (Player)content; // We add a new Effect to the player Effect?newEffect = PlayerLevelsUp(player); // If a new effect was chosen if (newEffect != null) { // We add the effect to the Player player.effects.Add((Effect)newEffect); // We raise the event : an Effect has been added When_Player_LevelsUp?.Invoke(player); } break; // otherwise : Error (should not occur, but we're not taking any chance) default: CONSOLE.WriteLine(ConsoleColor.Red, "Message instruction not understood : " + instruction); break; } } }
/// <summary> /// Creates a new Team /// </summary> private void NewTeam() { bool continueNewTeam = true; string errorMessage = ""; while (continueNewTeam) { // Displaying some messages Console.Clear(); CONSOLE.WriteLine(ConsoleColor.Blue, "\n Enter empty fields to leave the Creation of the new TEAM"); // Displays a message if the credentials are incorrect CONSOLE.WriteLine(ConsoleColor.Red, errorMessage); // NAME Console.Write("\n Please enter the name of the Team : "); string name = Console.ReadLine(); // DESCRIPTION Console.Write("\n Please enter the description of the Team : "); string description = Console.ReadLine(); // All the fields are empty : go back to the menu if (name.Length == 0 && description.Length == 0) { continueNewTeam = false; } // One of the field is empty : error else if (name.Length == 0 || description.Length == 0) { errorMessage = PrefabMessages.INCOMPLETE_FIELDS; } else if (name.Length > PrefabMessages.INPUT_MAXSIZE_STRUCTURE_NAME || description.Length > PrefabMessages.INPUT_MAXSIZE_STRUCTURE_DESCRIPTION) { errorMessage = PrefabMessages.INCORRECT_INPUT_SIZE; } // If at least one field has one incorrect character : ERROR else if (!Util.CorrectInput(name) || !Util.CorrectInput(description)) { errorMessage = PrefabMessages.INCORRECT_INPUT_CHARACTER; } // Otherwise : continue the protocol by choosing a Race else { // We create a list of all the Races List <Race> races = RaceStuff.GetAllRaces(); // CHOICE // We dynamically create a List containing all the Race's name List <string> choiceString = new List <string>(); races.ForEach(r => choiceString.Add(r.name())); // We add as a last choice the option to cancel the protocol choiceString.Add("Cancel the creation"); // We create the Choice Choice choice = new Choice("please Select a Race (last one = cancel) : ", choiceString); int index = choice.GetChoice(); // The user chose a Race if (index != choiceString.Count - 1) { // We get the race chose by the user Race race = races[index]; // Sending the new Team Instructions instruction = Instructions.Team_New; Team newTeam = new Team(name, description, race, userData); Net.COMMUNICATION.Send(comm.GetStream(), new Communication(instruction, newTeam)); // We receive the id of the Team from the server Guid idReceived = Net.GUID.Receive(comm.GetStream()); // We see if the id received is valid if (idReceived != Guid.Empty) { // We set the received id newTeam.id = idReceived; // We add the Player to the user's team userData.teams.Add(newTeam); // We display a success message CONSOLE.WriteLine(ConsoleColor.Green, PrefabMessages.TEAM_CREATION_SUCCESS); // Ending the loop continueNewTeam = false; } else { errorMessage = PrefabMessages.TEAM_CREATION_FAILURE; } } // The user chose to leave else { continueNewTeam = false; } } } }