public DATCONST1 LoginResponseMessage() { DATCONST1 message = DATCONST1.NICE_TRY_HAXOR; switch (m_login_reply) { case LoginReply.LoggedIn: message = DATCONST1.LOGIN_ACCOUNT_ALREADY_LOGGED_ON; break; case LoginReply.Busy: message = DATCONST1.CONNECTION_SERVER_IS_FULL; break; case LoginReply.WrongUser: message = DATCONST1.LOGIN_ACCOUNT_NAME_NOT_FOUND; break; case LoginReply.WrongUserPass: message = DATCONST1.LOGIN_ACCOUNT_NAME_OR_PASSWORD_NOT_FOUND; break; } return(message); }
public DATCONST1 AccountResponseMessage() { DATCONST1 ret = DATCONST1.NICE_TRY_HAXOR; switch (m_account_reply) { case AccountReply.Exists: ret = DATCONST1.ACCOUNT_CREATE_NAME_EXISTS; break; case AccountReply.NotApproved: ret = DATCONST1.ACCOUNT_CREATE_NAME_NOT_APPROVED; break; case AccountReply.Created: ret = DATCONST1.ACCOUNT_CREATE_SUCCESS_WELCOME; break; case AccountReply.ChangeFailed: ret = DATCONST1.CHANGE_PASSWORD_MISMATCH; break; case AccountReply.ChangeSuccess: ret = DATCONST1.CHANGE_PASSWORD_SUCCESS; break; } return(ret); }
public DATCONST1 CharacterResponseMessage() { DATCONST1 message = DATCONST1.NICE_TRY_HAXOR; switch (m_character_reply) { case CharacterReply.Ok: message = DATCONST1.CHARACTER_CREATE_SUCCESS; break; case CharacterReply.Full: message = DATCONST1.CHARACTER_CREATE_TOO_MANY_CHARS; break; case CharacterReply.Exists: message = DATCONST1.CHARACTER_CREATE_NAME_EXISTS; break; case CharacterReply.NotApproved: message = DATCONST1.CHARACTER_CREATE_NAME_NOT_APPROVED; break; } return(message); }
//Gets a localized string based on the selected language public static string GetString(DATCONST1 id, bool getTitle) { return(Instance.DataFiles[Instance.Localized1].Data[(int)id + (getTitle ? 0 : 1)]); }
//Gets a localized string based on the selected language public static string GetString(DATCONST1 id, bool getTitle) { return Instance.DataFiles[Instance.Localized1].Data[(int)id + (getTitle ? 0 : 1)]; }
//Pretty much controls how states transition between one another private void MainButtonPress(object sender, EventArgs e) { if (!IsActive) { return; } if (World.Instance.SoundEnabled && mainButtons.Contains(sender)) { SoundManager.GetSoundEffectRef(SoundEffectID.ButtonClick).Play(); } //switch on sender if (sender == mainButtons[0]) { //try connect //if successful go to account creation state TryConnectToServer(() => { doStateChange(GameStates.CreateAccount); EOScrollingDialog createAccountDlg = new EOScrollingDialog(""); string message = World.Instance.DataFiles[World.Instance.Localized2].Data[(int)DATCONST2.ACCOUNT_CREATE_WARNING_DIALOG_1]; message += "\n\n"; message += World.Instance.DataFiles[World.Instance.Localized2].Data[(int)DATCONST2.ACCOUNT_CREATE_WARNING_DIALOG_2]; message += "\n\n"; message += World.Instance.DataFiles[World.Instance.Localized2].Data[(int)DATCONST2.ACCOUNT_CREATE_WARNING_DIALOG_3]; createAccountDlg.MessageText = message; }); } else if (sender == mainButtons[1]) { //try connect //if successful go to account login state TryConnectToServer(() => doStateChange(GameStates.Login)); } else if (sender == mainButtons[2]) { doStateChange(GameStates.ViewCredits); } else if (sender == mainButtons[3]) { if (World.Instance.Client.ConnectedAndInitialized) { World.Instance.Client.Disconnect(); } Exit(); } else if ((sender == backButton && currentState != GameStates.PlayingTheGame) || sender == createButtons[1] || sender == loginButtons[1]) { Dispatcher.Subscriber = null; LostConnectionDialog(); //disabled warning: in case I add code later below, need to remember that this should immediately return // ReSharper disable once RedundantJumpStatement return; } else if (sender == backButton && currentState == GameStates.PlayingTheGame) { EODialog.Show(DATCONST1.EXIT_GAME_ARE_YOU_SURE, XNADialogButtons.OkCancel, EODialogStyle.SmallDialogSmallHeader, (ss, ee) => { if (ee.Result == XNADialogResult.OK) { Dispatcher.Subscriber = null; World.Instance.ResetGameElements(); if (World.Instance.Client.ConnectedAndInitialized) { World.Instance.Client.Disconnect(); } doStateChange(GameStates.Initial); } }); } else if (sender == loginButtons[0]) { if (loginUsernameTextbox.Text == "" || loginPasswordTextbox.Text == "") { return; } LoginReply reply; CharacterRenderData[] dataArray; if (!m_packetAPI.LoginRequest(loginUsernameTextbox.Text, loginPasswordTextbox.Text, out reply, out dataArray)) { LostConnectionDialog(); return; } if (reply != LoginReply.Ok) { EODialog.Show(m_packetAPI.LoginResponseMessage()); return; } World.Instance.MainPlayer.SetAccountName(loginUsernameTextbox.Text); World.Instance.MainPlayer.ProcessCharacterData(dataArray); doStateChange(GameStates.LoggedIn); } else if (sender == createButtons[0]) { switch (currentState) { case GameStates.CreateAccount: { if (accountCreateTextBoxes.Any(txt => txt.Text.Length == 0)) { EODialog.Show(DATCONST1.ACCOUNT_CREATE_FIELDS_STILL_EMPTY); return; } if (accountCreateTextBoxes[0].Text.Length < 4) { EODialog.Show(DATCONST1.ACCOUNT_CREATE_NAME_TOO_SHORT); return; } if (accountCreateTextBoxes[0].Text.Distinct().Count() < 3) { EODialog.Show(DATCONST1.ACCOUNT_CREATE_NAME_TOO_OBVIOUS); return; } if (accountCreateTextBoxes[1].Text != accountCreateTextBoxes[2].Text) { EODialog.Show(DATCONST1.ACCOUNT_CREATE_PASSWORD_MISMATCH); return; } if (accountCreateTextBoxes[1].Text.Length < 6) { EODialog.Show(DATCONST1.ACCOUNT_CREATE_PASSWORD_TOO_SHORT); return; } if (accountCreateTextBoxes[1].Text.Distinct().Count() < 3) { EODialog.Show(DATCONST1.ACCOUNT_CREATE_PASSWORD_TOO_OBVIOUS); return; } if (!System.Text.RegularExpressions.Regex.IsMatch(accountCreateTextBoxes[5].Text, //filter emails using regex @"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|asia|jobs|museum)\b")) { EODialog.Show(DATCONST1.ACCOUNT_CREATE_EMAIL_INVALID); return; } AccountReply reply; if (!m_packetAPI.AccountCheckName(accountCreateTextBoxes[0].Text, out reply)) { LostConnectionDialog(); return; } if (reply != AccountReply.Continue) { EODialog.Show(m_packetAPI.AccountResponseMessage()); return; } //show progress bar for account creation pending and THEN create the account string pbmessage = World.Instance.DataFiles[World.Instance.Localized1].Data[(int)DATCONST1.ACCOUNT_CREATE_ACCEPTED + 1]; string pbcaption = World.Instance.DataFiles[World.Instance.Localized1].Data[(int)DATCONST1.ACCOUNT_CREATE_ACCEPTED]; EOProgressDialog dlg = new EOProgressDialog(pbmessage, pbcaption); dlg.DialogClosing += (dlg_S, dlg_E) => { if (dlg_E.Result != XNADialogResult.NO_BUTTON_PRESSED) { return; } if (!m_packetAPI.AccountCreate(accountCreateTextBoxes[0].Text, accountCreateTextBoxes[1].Text, accountCreateTextBoxes[3].Text, accountCreateTextBoxes[4].Text, accountCreateTextBoxes[5].Text, Config.GetHDDSerial(), out reply)) { LostConnectionDialog(); return; } DATCONST1 resource = m_packetAPI.AccountResponseMessage(); if (reply != AccountReply.Created) { EODialog.Show(resource); return; } doStateChange(GameStates.Initial); EODialog.Show(resource); }; } break; case GameStates.LoggedIn: { //Character_request: show create character dialog //Character_create: clicked ok in create character dialog CharacterReply reply; if (!m_packetAPI.CharacterRequest(out reply)) { LostConnectionDialog(); return; } if (reply != CharacterReply.Ok) { EODialog.Show("Server is not allowing you to create a character right now. This could be a bug.", "Server error"); return; } EOCreateCharacterDialog createCharacter = new EOCreateCharacterDialog(textBoxTextures[3], Dispatcher); createCharacter.DialogClosing += (dlg_S, dlg_E) => { if (dlg_E.Result != XNADialogResult.OK) { return; } CharacterRenderData[] dataArray; if (!m_packetAPI.CharacterCreate(createCharacter.Gender, createCharacter.HairType, createCharacter.HairColor, createCharacter.SkinColor, createCharacter.Name, out reply, out dataArray)) { LostConnectionDialog(); return; } if (reply != CharacterReply.Ok) { if (reply != CharacterReply.Full) { dlg_E.CancelClose = true; } EODialog.Show(m_packetAPI.CharacterResponseMessage()); return; } EODialog.Show(DATCONST1.CHARACTER_CREATE_SUCCESS); World.Instance.MainPlayer.ProcessCharacterData(dataArray); doShowCharacters(); }; } break; } } else if (sender == passwordChangeBtn) { EOChangePasswordDialog dlg = new EOChangePasswordDialog(textBoxTextures[3], Dispatcher); dlg.DialogClosing += (dlg_S, dlg_E) => { if (dlg_E.Result != XNADialogResult.OK) { return; } AccountReply reply; if (!m_packetAPI.AccountChangePassword(dlg.Username, dlg.OldPassword, dlg.NewPassword, out reply)) { LostConnectionDialog(); return; } EODialog.Show(m_packetAPI.AccountResponseMessage()); if (reply == AccountReply.ChangeSuccess) { return; } dlg_E.CancelClose = true; }; } }
//-------------------------- //***** HELPER METHODS ***** //-------------------------- private async Task TryConnectToServer(Action successAction) { //the mutex here should simulate the action of spamming the button. //no matter what, it will only do it one at a time: the mutex is only released when the bg thread ends if (connectMutex == null) { connectMutex = new AutoResetEvent(true); if (!connectMutex.WaitOne(0)) { return; } } else if (!connectMutex.WaitOne(0)) { return; } if (World.Instance.Client.ConnectedAndInitialized && World.Instance.Client.Connected) { successAction(); connectMutex.Set(); return; } //execute this logic on a separate thread so the game doesn't lock up while it's trying to connect to the server await TaskFramework.Run(() => { try { if (World.Instance.Client.ConnectToServer(host, port)) { m_packetAPI = new PacketAPI((EOClient)World.Instance.Client); //set up event packet handling event bindings: // some events are triggered by the server regardless of action by the client m_callbackManager = new PacketAPICallbackManager(m_packetAPI, this); m_callbackManager.AssignCallbacks(); ((EOClient)World.Instance.Client).EventDisconnect += () => m_packetAPI.Disconnect(); InitData data; if (m_packetAPI.Initialize(World.Instance.VersionMajor, World.Instance.VersionMinor, World.Instance.VersionClient, Win32.GetHDDSerial(), out data)) { switch (data.ServerResponse) { case InitReply.INIT_OK: ((EOClient)World.Instance.Client).SetInitData(data); if (!m_packetAPI.ConfirmInit(data.emulti_e, data.emulti_d, data.clientID)) { throw new Exception(); //connection failed! } World.Instance.MainPlayer.SetPlayerID(data.clientID); World.Instance.SetAPIHandle(m_packetAPI); successAction(); break; default: string extra; DATCONST1 msg = m_packetAPI.GetInitResponseMessage(out extra); EODialog.Show(msg, extra); break; } } else { throw new Exception(); //connection failed! } } else { //show connection not found throw new Exception(); } } catch { if (!exiting) { EODialog.Show(DATCONST1.CONNECTION_SERVER_NOT_FOUND); } } connectMutex.Set(); }); }
public static void Show(DATCONST1 resource, string extraData, XNADialogButtons whichButtons = XNADialogButtons.Ok, EOMessageBoxStyle style = EOMessageBoxStyle.SmallDialogLargeHeader, OnDialogClose closingEvent = null) { if (!World.Initialized) throw new WorldLoadException("Unable to create dialog! World must be loaded and initialized."); EDFFile file = World.Instance.DataFiles[World.Instance.Localized1]; string message = file.Data[(int)resource + 1] + extraData; Show(message, file.Data[(int)resource], whichButtons, style, closingEvent); }