private bool PerformDupeCheck(DescriptorData descriptor) { long ID = descriptor.Character.CharacterSpecials.Saved.IDNumber; CharacterData target = null; DupeMode mode = DupeMode.None; foreach (DescriptorData cycle in _descriptors) { if (descriptor == cycle) continue; if (cycle.Original != null && cycle.Original.CharacterSpecials.Saved.IDNumber == ID) { WriteToOutput(descriptor, "\r\nMultiple login detected -- disconnecting.\r\n"); descriptor.ConnectState = ConnectState.Close; if (target == null) { target = cycle.Original; mode = DupeMode.Unswitch; } if (cycle.Character != null) cycle.Character.Descriptor = null; cycle.Character = null; cycle.Original = null; } else if (cycle.Character != null && cycle.Character.CharacterSpecials.Saved.IDNumber == ID && cycle.Original != null) { DoReturn(cycle.Character, null, 0, 0); } else if (cycle.Character != null && cycle.Character.CharacterSpecials.Saved.IDNumber == ID) { if (target == null && cycle.ConnectState == ConnectState.Playing) { WriteToOutput(cycle, "\r\nThis body has been usurped!\r\n"); target = cycle.Character; mode = DupeMode.Usurp; } cycle.Character.Descriptor = null; cycle.Character = null; cycle.Original = null; WriteToOutput(cycle, "\r\nMultiple login detected -- disconnecting.\r\n"); cycle.ConnectState = ConnectState.Close; } } foreach (CharacterData cycle in _characters) { if (cycle.MobileFlagged(MobileFlags.IsNPC)) continue; if (cycle.CharacterSpecials.Saved.IDNumber != ID) continue; if (cycle.Descriptor != null) continue; if (cycle == target) continue; if (target == null) { target = cycle; mode = DupeMode.Recon; continue; } if (target == null) return false; FreeCharacter(descriptor.Character); descriptor.Character = target; descriptor.Character.Descriptor = descriptor; descriptor.Original = null; descriptor.Character.CharacterSpecials.Timer = 0; descriptor.Character.RemovePlayerFlag(PlayerFlags.Writing); descriptor.Character.RemovePlayerFlag(PlayerFlags.Mailing); descriptor.Character.RemoveAffectFlag(AffectFlags.Group); descriptor.ConnectState = ConnectState.Playing; switch (mode) { case DupeMode.Recon: WriteToOutput(descriptor, "Reconnecting.\r\n"); Act("$n has reconnected.", true, descriptor.Character, null, null, GlobalConstants.TO_ROOM); //mudlog(NRM, MAX(LVL_IMMORT, GET_INVIS_LEV(d->character)), TRUE, "%s [%s] has reconnected.", GET_NAME(d->character), d->host); if (HasMail(descriptor.Character.CharacterSpecials.Saved.IDNumber)) WriteToOutput(descriptor, "You have mail waiting.\r\n"); // FIXME: Something about ZLIB? break; case DupeMode.Usurp: WriteToOutput(descriptor, "You take over your own body, already in use!\r\n"); Act("$n suddenly keels over in pain, surrounded by a white aura...\r\n" + "$n's body has been taken over by a new spirit!", true, descriptor.Character, null, null, GlobalConstants.TO_ROOM); //mudlog(NRM, MAX(LVL_IMMORT, GET_INVIS_LEV(d->character)), TRUE, "%s has re-logged in ... disconnecting old socket.", GET_NAME(d->character)); break; case DupeMode.Unswitch: WriteToOutput(descriptor, "Reconnecting to unswitched character."); //mudlog(NRM, MAX(LVL_IMMORT, GET_INVIS_LEV(d->character)), TRUE, "%s [%s] has reconnected.", GET_NAME(d->character), d->host); break; } } return true; }
private void DisplayRaces(DescriptorData descriptor) { SendToCharacter(descriptor.Character, "\r\n@YRace Selection Menu:\r\n----------------------\r\n@n"); for (int i = 0; i < (int)RaceTypes.Index; i++) if (RaceGenderMatrix[(int)descriptor.Character.Player.Sex, i]) SendToCharacter(descriptor.Character, "[" + i + "] " + ((RaceTypes)i).ToString()); SendToCharacter(descriptor.Character, "\n@WRace@n: "); }
private void Nanny(DescriptorData descriptor, string input) { string tmpName = String.Empty; // If there is no character object yet, we need to create one. if (descriptor.Character == null) { descriptor.Character = new CharacterData(); descriptor.Character.Descriptor = descriptor; } // TODO: OLC states here. // Not in OLC, lets do regular welcome. switch (descriptor.ConnectState) { case ConnectState.GetName: if (descriptor.Character == null) { descriptor.Character = new CharacterData(); descriptor.Character.Descriptor = descriptor; } if (input.Length == 0) descriptor.ConnectState = ConnectState.Close; else { if (!ParseName(input, out tmpName) || tmpName.Length < 2 || tmpName.Length > 25 || !ValidName(tmpName) || FillWord(tmpName) || ReservedWord(tmpName)) { WriteToOutput(descriptor, "Invalid name, please try another.\r\nPlease provide your name: "); return; } } if (LoadCharacter(tmpName, descriptor.Character)) { if (descriptor.Character.PlayerFlagged(PlayerFlags.Deleted)) { RemovePlayer(descriptor.Character); descriptor.Character = null; FreeCharacter(descriptor.Character); if (!ValidName(tmpName)) { WriteToOutput(descriptor, "Invalid name, please try another.\r\nPlease provide your name: "); return; } descriptor.Character = new CharacterData(); descriptor.Character.Descriptor = descriptor; descriptor.Character.Player.Name = GlobalUtilities.Capital(tmpName); WriteToOutput(descriptor, "Did I get that right, @Y" + tmpName + "@n [Y/N]? "); descriptor.ConnectState = ConnectState.NameConfirm; } else { /* undo it just in case they are set */ descriptor.Character.RemovePlayerFlag(PlayerFlags.Writing); descriptor.Character.RemovePlayerFlag(PlayerFlags.Mailing); descriptor.Character.RemovePlayerFlag(PlayerFlags.Cryo); descriptor.Character.RemoveAffectFlag(AffectFlags.Group); descriptor.Character.Player.Time.Logon = DateTime.Now; WriteToOutput(descriptor, "Please enter the @gpassword@n: "); EchoOff(descriptor); descriptor.IdleTicks = 0; descriptor.ConnectState = ConnectState.Password; } } else { if (!ValidName(tmpName)) { WriteToOutput(descriptor, "Invalid name, please try another.\r\nPlease provide your name: "); return; } descriptor.Character.Player.Name = tmpName; WriteToOutput(descriptor, "Did I get that right, @Y" + tmpName + "@n [Y/N]?"); descriptor.ConnectState = ConnectState.NameConfirm; } break; case ConnectState.NameConfirm: if (input.ToLower()[0] == 'y') { if (IsBanned(descriptor.Hostname) > BanTypes.New) { //mudlog(NRM, LVL_GOD, TRUE, "Request for new char %s denied from [%s] (siteban)", GET_PC_NAME(d->character), d->host); WriteToOutput(descriptor, "@RSorry, new characters are not allowed from your site!@n\r\n"); descriptor.ConnectState = ConnectState.Close; return; } if (GlobalSettings.UserRestriction > 0) { WriteToOutput(descriptor, "@RSorry, new players can't be created at the moment.@n\r\n"); //mudlog(NRM, LVL_GOD, TRUE, "Request for new char %s denied from [%s] (wizlock)", GET_PC_NAME(d->character), d->host); descriptor.ConnectState = ConnectState.Close; return; } WriteToOutput(descriptor, "@MNew Character!@n\r\nProvide a new @gpassword@n: "); EchoOff(descriptor); descriptor.ConnectState = ConnectState.NewPassword; } else if (input.ToLower()[0] == 'n') { WriteToOutput(descriptor, "Okay, then what IS your name: "); descriptor.Character.Player.Name = String.Empty; descriptor.ConnectState = ConnectState.GetName; } else WriteToOutput(descriptor, "Please type Yes or No [Y/N]: "); break; case ConnectState.Password: EchoOn(descriptor); WriteToOutput(descriptor, "\r\n"); // New EchoOn() eats the return on telnet, an extra space helps just in case. if (String.IsNullOrEmpty(input)) descriptor.ConnectState = ConnectState.Close; else { if (descriptor.Character.Player.Password.CompareTo(input) != 0) { //mudlog(BRF, LVL_GOD, TRUE, "Bad PW: %s [%s]", GET_NAME(d->character), d->host); descriptor.Character.PlayerSpecials.Saved.BadPasswords++; SaveCharacter(descriptor.Character); if (++descriptor.BadPasswords >= GlobalConstants.MAX_BAD_PWS) { WriteToOutput(descriptor, "@RWrong password... disconnecting.@n\r\n"); descriptor.ConnectState = ConnectState.Close; } else { WriteToOutput(descriptor, "@RWrong password@n. Please provide the @gpassword@n: "); EchoOff(descriptor); } return; } int hadBadPasswords = descriptor.Character.PlayerSpecials.Saved.BadPasswords; descriptor.Character.PlayerSpecials.Saved.BadPasswords = 0; descriptor.BadPasswords = 0; if (IsBanned(descriptor.Hostname) == BanTypes.Select && descriptor.Character.PlayerFlagged(PlayerFlags.SiteOK)) { WriteToOutput(descriptor, "Sorry, this character has not been cleared to login from your site!\r\n"); descriptor.ConnectState = ConnectState.Close; //mudlog(NRM, LVL_GOD, TRUE, "Connection attempt for %s denied from %s", GET_NAME(d->character), d->host); return; } if (descriptor.Character.Player.Level < GlobalSettings.UserRestriction) { WriteToOutput(descriptor, "The game is temporarily restricted... please try again later.\r\n"); descriptor.ConnectState = ConnectState.Close; //mudlog(NRM, LVL_GOD, TRUE, "Request for login denied for %s [%s] (wizlock)", GET_NAME(d->character), d->host); return; } if (PerformDupeCheck(descriptor)) return; if (descriptor.Character.Player.Level >= GlobalConstants.LVL_IMMORT) WriteToOutput(descriptor, _textIMOTD); else WriteToOutput(descriptor, _textMOTD); //if (descriptor.Character.PlayerSpecials.Saved.InvisibleLevel > 0) //mudlog(BRF, MAX(LVL_IMMORT, GET_INVIS_LEV(d->character)), TRUE, "%s [%s] has connected. (invis %d)", GET_NAME(d->character), d->host, GET_INVIS_LEV(d->character)); //else //mudlog(BRF, LVL_IMMORT, TRUE, "%s [%s] has connected.", GET_NAME(d->character), d->host); if (hadBadPasswords > 0) { WriteToOutput(descriptor, "\r\n\r\n\007\007\007@R" + hadBadPasswords + " LOGIN FAILURE(S) SINCE LAST SUCCESSFUL LOGIN.@n\r\n"); descriptor.Character.PlayerSpecials.Saved.BadPasswords = 0; } WriteToOutput(descriptor, "\r\n*** PRESS RETURN: "); descriptor.ConnectState = ConnectState.RMOTD; } break; case ConnectState.NewPassword: case ConnectState.ChangePasswordGetNew: if (String.IsNullOrEmpty(input) || input.Length > GlobalConstants.MAX_PWD_LENGTH || input.Length < 3 || descriptor.Character.Player.Name.CompareTo(input) == 0) { WriteToOutput(descriptor, "\r\nIllegal password.\r\nPlease provide your @gpassword@n: "); return; } descriptor.Character.Player.Password = input; WriteToOutput(descriptor, "\r\nPlease retype your @gpassword@n: "); if (descriptor.ConnectState == ConnectState.NewPassword) descriptor.ConnectState = ConnectState.ConfirmPassword; else descriptor.ConnectState = ConnectState.ChangePasswordVerify; break; case ConnectState.ConfirmPassword: case ConnectState.ChangePasswordVerify: if (descriptor.Character.Player.Password.CompareTo(input) != 0) { WriteToOutput(descriptor, "\r\nPasswords do not match... start over.\r\nPlease provide your @gpassword@n: "); if (descriptor.ConnectState == ConnectState.ConfirmPassword) descriptor.ConnectState = ConnectState.NewPassword; else descriptor.ConnectState = ConnectState.ChangePasswordGetNew; return; } EchoOn(descriptor); if (descriptor.ConnectState == ConnectState.ConfirmPassword) { WriteToOutput(descriptor, "\r\nWhat is your character's sex [M/F]: "); descriptor.ConnectState = ConnectState.QuestionSex; } else { SaveCharacter(descriptor.Character); WriteToOutput(descriptor, "\r\nDone.\r\n" + _textMenu); descriptor.ConnectState = ConnectState.Menu; } break; case ConnectState.QuestionSex: switch (input.ToLower()[0]) { case 'm': descriptor.Character.Player.Sex = SexTypes.Male; break; case 'f': descriptor.Character.Player.Sex = SexTypes.Female; break; case 'n': descriptor.Character.Player.Sex = SexTypes.Neutral; break; default: WriteToOutput(descriptor, "That is not a sex..\r\nWhat IS your character's sex [M/F]: "); return; } DisplayRaces(descriptor); descriptor.ConnectState = ConnectState.QuestionRace; break; case ConnectState.QuestionRace: RaceTypes race = (RaceTypes)int.Parse(input); if (race == RaceTypes.Undefined) { WriteToOutput(descriptor, "\r\nThat's not a race.\r\nRace: "); return; } else descriptor.Character.Player.Race = race; DisplayClasses(descriptor); descriptor.ConnectState = ConnectState.QuestionClass; break; case ConnectState.QuestionClass: ClassTypes cls = (ClassTypes)int.Parse(input); if (cls == ClassTypes.Undefined) { WriteToOutput(descriptor, "\r\nThat's not a class.\r\nClass: "); return; } else descriptor.Character.Player.Class = cls; WriteToOutput(descriptor, "\r\n*** PRESS RETURN: "); descriptor.ConnectState = ConnectState.QuestionRollStats; break; case ConnectState.QuestionRollStats: break; } }
private void WriteToOutput(DescriptorData descriptor, byte[] bytes) { // this is to add data to the output buffer (queue) to be sent out. // Add the bytes to a new byte array with both. byte[] totalBytes = new byte[bytes.Length + descriptor.Output.Length]; Array.Copy(descriptor.Output, 0, totalBytes, 0, descriptor.Output.Length); Array.Copy(bytes, 0, totalBytes, descriptor.Output.Length, bytes.Length); descriptor.Output = totalBytes; }
private void DisplayClasses(DescriptorData descriptor) { SendToCharacter(descriptor.Character, "\r\n@YClass Selection Menu:\r\n---------------------\r\n@n"); for (int i = 0; i < (int)ClassTypes.Index; i++) if (RaceClassMatrix[(int)descriptor.Character.Player.Race, i]) SendToCharacter(descriptor.Character, "[" + i + "] " + ((ClassTypes)i).ToString()); SendToCharacter(descriptor.Character, "\n@WClass@n: "); }
private int WriteToDescriptor(DescriptorData descriptor, string text) { int bytesWritten = descriptor.Connection.Client.Send(Encoding.UTF8.GetBytes(text)); return (bytesWritten); }
private void WriteToOutput(DescriptorData descriptor, string text) { WriteToOutput(descriptor, Encoding.UTF8.GetBytes(ProcessColors(text))); }
private void ProcessOutput(DescriptorData descriptor) { byte[] output = new byte[0]; string end = "\r\n"; //output += descriptor.Output; // TODO: Deal with overflow? //if (descriptor.ConnectState == ConnectState.Playing && descriptor.Character != null && !descriptor.Character.IsNPC && !descriptor.Character.PreferenceFlagged (PRF_COMPACT)) // output += "\r\n"; end += MakePrompt(descriptor); if (descriptor.HasPrompt) { descriptor.HasPrompt = false; WriteToDescriptor(descriptor, end); } else { WriteToDescriptor(descriptor, descriptor.Output); // TODO: Output to Snooper descriptor.Output = new byte[0]; } }
private int WriteToDescriptor(DescriptorData descriptor, byte[] bytes) { int bytesWritten = descriptor.Connection.Client.Send(bytes); return (bytesWritten); }
private int ProcessInput(DescriptorData descriptor) { byte[] buffer = new byte[descriptor.Connection.Available]; TcpClient tcpClient = descriptor.Connection; try { // Test the socket descriptor.Connection.Client.Send(Encoding.UTF8.GetBytes("\0")); } catch (SocketException ex) { return -1; } if (descriptor.Connection.Available > 0) { int position = descriptor.RawInputBuffer.Length; // Receive available data from the client connection. descriptor.Connection.Client.Receive(buffer); char[] destination = descriptor.RawInputBuffer; char[] charbuffer = Encoding.UTF8.GetChars(buffer); Array.Resize(ref destination, destination.Length + charbuffer.Length); Array.Copy(charbuffer, 0, destination, position, charbuffer.Length); descriptor.RawInputBuffer = destination; // Now we have put the raw buffer together with the new data. int indexNL = -1; // Look for a new line within the data. for (int i = 0; i < descriptor.RawInputBuffer.Length; i++) { if (descriptor.RawInputBuffer[i] == '\r' || descriptor.RawInputBuffer[i] == '\n') { indexNL = i; break; } } if (indexNL < 0) return 0; while (indexNL >= 0) { char[] commandbuffer = new char[indexNL]; string command = String.Empty; Array.Copy(descriptor.RawInputBuffer, 0, commandbuffer, 0, indexNL); char[] remainingbuffer = new char[descriptor.RawInputBuffer.Length - indexNL - 1]; Array.Copy(descriptor.RawInputBuffer, indexNL + 1, remainingbuffer, 0, descriptor.RawInputBuffer.Length - indexNL - 1); descriptor.RawInputBuffer = remainingbuffer; indexNL = -1; for (int i = 0; i < descriptor.RawInputBuffer.Length; i++) { if (descriptor.RawInputBuffer[i] == '\r' || descriptor.RawInputBuffer[i] == '\n') { indexNL = i; break; } } if (commandbuffer.Length > 0) { foreach (char c in commandbuffer) { if (c == '\b' || c == 127) command = command.Substring(0, command.Length - 1); else command += c; } // TODO: Worry about who to show this command to (snooping). // TODO: Worry about substitution and repetition (^ and !) descriptor.LastInput = command; // TODO: Work with history. descriptor.InputQueue.Enqueue(command); } else if (commandbuffer.Length == 0 && indexNL != -1) { descriptor.InputQueue.Enqueue(""); } } } return (buffer.Length); }
private void NewDescriptor(TcpClient client) { DescriptorData descriptor = new DescriptorData(client); if (_descriptors.Count >= GlobalSettings.MaximumPlayers) { WriteToDescriptor(descriptor, "Sorry, the system is full right now... please try again later!\r\n"); client.Close(); return; } descriptor.Hostname = Dns.GetHostEntry(client.Client.RemoteEndPoint.ToString().Split(':')[0]).HostName; foreach (BanListElement element in _bans) { if (descriptor.Hostname.Equals(element.Site)) if (element.Type == BanTypes.All) { WriteToDescriptor(descriptor, "You have been banned.\r\n"); client.Close(); return; } } // TODO: Notify of the new connection in the Mud Log. //mudlog(CMP, LVL_GOD, FALSE, "New connection from [%s]", newd->host); descriptor.IdleTicks = 0; descriptor.LoginTime = DateTime.Now; descriptor.HasPrompt = true; descriptor.ConnectState = ConnectState.GetName; _descriptors.Add(descriptor); WriteToOutput(descriptor, _textGreetings); }
private string MakePrompt(DescriptorData descriptor) { return ">"; }
private void EchoOn(DescriptorData descriptor) { byte[] bytes = new byte[4] { (byte)GlobalConstants.IAC, (byte)GlobalConstants.WONT, (byte)GlobalConstants.TELOPT_ECHO, (byte)0 }; WriteToOutput(descriptor, bytes); }
private void CloseSocket(DescriptorData descriptor) { _descriptors.Remove(descriptor); descriptor.Connection.Close(); // Forget Snooping // Reset the switched mobiles/snooping/etc // Clear command history // Clear any OLC stuff }