Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

[Release] Launcher Complete w/ Source Code

Life is beautiful, after
Joined
Aug 21, 2019
Messages
632
Reaction score
456
wSugyCT - [Release] Launcher Complete w/ Source Code - RaGEZONE Forums


This release is a launcher for the Play BD Legends private server. I admit this launcher is the most beautiful I've seen in all this time.

It is not just any launcher, it has an auto updater, checking if the server is online or not, login in the launcher itself where it checks if the player has a registered account or not, website news, slides with redirection links.

The launcher itself is very simple and normal code, however it pulls JSON files to perform some tasks, I think this can be changed easily.

Pictures
dzwWgc0 - [Release] Launcher Complete w/ Source Code - RaGEZONE Forums


UCWr0Fb - [Release] Launcher Complete w/ Source Code - RaGEZONE Forums


nXvqb24 - [Release] Launcher Complete w/ Source Code - RaGEZONE Forums

Files

JSON FILES ARE ATTACHED TO THE THREAD

Who made this launcher: Norea
 

Attachments

You must be registered for see attachments list
Last edited:
Life is beautiful, after
Joined
Aug 21, 2019
Messages
632
Reaction score
456
Here go


 

Attachments

You must be registered for see attachments list
Banned
Banned
Joined
Jan 25, 2023
Messages
125
Reaction score
36
I succeeded.
1694852501980 - [Release] Launcher Complete w/ Source Code - RaGEZONE Forums


Source code for this logger:
1, I can't use the online update file.
I guess {"name": "pad00000.meta", "version":1, "folder": "Paz/pad00000.meta", "url": " ",. "size":28952028, "last_modified":1646798543}
where "size":28952028, "last_modified":1646798543 requires a specialized tool to make these. (not tested)
2, lack of account registration API ???? In the source code location:\Launcher Main - PlayBD Legens\playbdlegends-main\Black Desert Legends\Controls\UserTab.xaml
You can find that there should be a registration function?The BtnLogin function is not there either. Maybe I don't know how to use it.
3, I compiled the login and used it in the Corsair 3506 version of the client, I clicked on the start button and it doesn't work. I checked and found that the Newtonsoft.Json.dll file compiled from the source code is not the same as the Newtonsoft.Json.dll in the 3506 version, I use the file in the 3506 client and the logoner flashes back, if I use the Newtonsoft.Json.dll compiled from the logoner then the logoner doesn't have any response.

That's all the problems found so far. Finally: I am a programming rookie and would like to have programming skills to improve this logger source code. I use translation software to translate.
 

Attachments

You must be registered for see attachments list
Last edited:
Newbie Spellweaver
Joined
Jan 16, 2015
Messages
5
Reaction score
9
here
I succeeded.
View attachment 241855

Source code for this logger:
1, I can't use the online update file.
I guess {"name": "pad00000.meta", "version":1, "folder": "Paz/pad00000.meta", "url": " ",. "size":28952028, "last_modified":1646798543}
where "size":28952028, "last_modified":1646798543 requires a specialized tool to make these. (not tested)
2, lack of account registration API ???? In the source code location:\Launcher Main - PlayBD Legens\playbdlegends-main\Black Desert Legends\Controls\UserTab.xaml
You can find that there should be a registration function?The BtnLogin function is not there either. Maybe I don't know how to use it.
3, I compiled the login and used it in the Corsair 3506 version of the client, I clicked on the start button and it doesn't work. I checked and found that the Newtonsoft.Json.dll file compiled from the source code is not the same as the Newtonsoft.Json.dll in the 3506 version, I use the file in the 3506 client and the logoner flashes back, if I use the Newtonsoft.Json.dll compiled from the logoner then the logoner doesn't have any response.

That's all the problems found so far. Finally: I am a programming rookie and would like to have programming skills to improve this logger source code. I use translation software to translate.

Here the src for a lister to make the list for updates
 

Attachments

You must be registered for see attachments list
Banned
Banned
Joined
Jan 25, 2023
Messages
125
Reaction score
36
here


Here the src for a lister to make the list for updates
Since I'm a programming rookie, can you give me a complete one? Thanks!

How do you create the login and account registration functions? There is no .Json file
 
Last edited:
Banned
Banned
Joined
Jan 25, 2023
Messages
125
Reaction score
36
The login is more complicated
I think you can implement all the features of this logger source code. I wonder if you would like to share or implement it?
 
Last edited:
Newbie Spellweaver
Joined
Jan 16, 2015
Messages
5
Reaction score
9
I think you can implement all the features of this logger source code. I wonder if you would like to share or implement it?
It requires setting up the api with the database, i'll give an easier solution.
With this method you can login with what you want and it will start the game with the given id+pw.

in Statics.cs under:
C#:
public static string LoginId = string.Empty;
add:
C#:
public static string LoginPw = string.Empty;

in LoginForm.xaml.cs replace entire:
C#:
private void BtnLogin_Click(object sender, RoutedEventArgs e)
with this:
C#:
        private void BtnLogin_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (!string.IsNullOrEmpty(UsernameCBOX.USERNAME.Text) && !string.IsNullOrEmpty(PasswordCBOX.PASSWORD.Password))
                {
                    Statics.LoginId = UsernameCBOX.USERNAME.Text;
                    Statics.LoginPw = PasswordCBOX.PASSWORD.Password;

                    Statics.mainWindow._UserTab.LogIn(Statics.LoginId);

                    Hide();
                }
                else
                {
                    ShowLoginError("ID and password are required.");
                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

in Launcher.xaml.cs in BtnPlay_Click replace this:
C#:
cmd.StandardInput.WriteLine("start blackdesert64.exe " + Statics.LoginId.ToString());
with this:
C#:
cmd.StandardInput.WriteLine("start blackdesert64.exe " + Statics.LoginId + "," + Statics.LoginPw);
 
Banned
Banned
Joined
Jan 25, 2023
Messages
125
Reaction score
36
非常感谢!
It requires setting up the api with the database, i'll give an easier solution.
With this method you can login with what you want and it will start the game with the given id+pw.

in Statics.cs under:
C#:
public static string LoginId = string.Empty;
add:
C#:
public static string LoginPw = string.Empty;

in LoginForm.xaml.cs replace entire:
C#:
private void BtnLogin_Click(object sender, RoutedEventArgs e)
with this:
C#:
        private void BtnLogin_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (!string.IsNullOrEmpty(UsernameCBOX.USERNAME.Text) && !string.IsNullOrEmpty(PasswordCBOX.PASSWORD.Password))
                {
                    Statics.LoginId = UsernameCBOX.USERNAME.Text;
                    Statics.LoginPw = PasswordCBOX.PASSWORD.Password;

                    Statics.mainWindow._UserTab.LogIn(Statics.LoginId);

                    Hide();
                }
                else
                {
                    ShowLoginError("ID and password are required.");
                }
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

in Launcher.xaml.cs in BtnPlay_Click replace this:
C#:
cmd.StandardInput.WriteLine("start blackdesert64.exe " + Statics.LoginId.ToString());
with this:
C#:
cmd.StandardInput.WriteLine("start blackdesert64.exe " + Statics.LoginId + "," + Statics.LoginPw);
Thank you very much! You're fantastic!

Is it possible to write it this way? Use the database to verify the account password, verify successfully to log in, if it is not in the database then it will automatically register, if the password is wrong then it will show to re-enter the password?
==========================================================================

private void BtnLogin_Click(object sender, RoutedEventArgs e)
{
try
{
string connectionString = "YourConnectionStringHere";
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();

string query = "SELECT * FROM Users WHERE Username = username";
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("username", UsernameCBOX.USERNAME.Text);

using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
string storedPassword = reader["Password"].ToString();
if (storedPassword == PasswordCBOX.PASSWORD.Password)
{
// 4. 存储登录信息
Statics.LoginId = UsernameCBOX.USERNAME.Text;
Statics.LoginPw = PasswordCBOX.PASSWORD.Password;
Hide();
}
else
{
// 6. 提示密码错误
ShowLoginError("Incorrect password. Please try again.");
}
}
}
else
{
// 5. 注册新用户
RegisterNewUser();
}
}
}
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}

private void RegisterNewUser()
{
try
{
string connectionString = "YourConnectionStringHere";
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();

string query = "INSERT INTO Users (Username, Password) VALUES (username, Password)";
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("username", UsernameCBOX.USERNAME.Text);
command.Parameters.AddWithValue("Password", PasswordCBOX.PASSWORD.Password);

int rowsAffected = command.ExecuteNonQuery();
if (rowsAffected > 0)
{
// 4. 存储登录信息
Statics.LoginId = UsernameCBOX.USERNAME.Text;
Statics.LoginPw = PasswordCBOX.PASSWORD.Password;
Hide();
}
else
{
ShowLoginError("User registration failed. Please try again.");
}
}
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}

private void ShowLoginError(string errorMessage)
{
MessageBox.Show(errorMessage);
}
 
Last edited:
Initiate Mage
Joined
Jul 20, 2014
Messages
4
Reaction score
0
非常感谢!

Thank you very much! You're fantastic!

Is it possible to write it this way? Use the database to verify the account password, verify successfully to log in, if it is not in the database then it will automatically register, if the password is wrong then it will show to re-enter the password?
==========================================================================

private void BtnLogin_Click(object sender, RoutedEventArgs e)
{
try
{
string connectionString = "YourConnectionStringHere";
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();

string query = "SELECT * FROM Users WHERE Username = username";
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("username", UsernameCBOX.USERNAME.Text);

using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
string storedPassword = reader["Password"].ToString();
if (storedPassword == PasswordCBOX.PASSWORD.Password)
{
// 4. 存储登录信息
Statics.LoginId = UsernameCBOX.USERNAME.Text;
Statics.LoginPw = PasswordCBOX.PASSWORD.Password;
Hide();
}
else
{
// 6. 提示密码错误
ShowLoginError("Incorrect password. Please try again.");
}
}
}
else
{
// 5. 注册新用户
RegisterNewUser();
}
}
}
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}

private void RegisterNewUser()
{
try
{
string connectionString = "YourConnectionStringHere";
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();

string query = "INSERT INTO Users (Username, Password) VALUES (username, Password)";
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("username", UsernameCBOX.USERNAME.Text);
command.Parameters.AddWithValue("Password", PasswordCBOX.PASSWORD.Password);

int rowsAffected = command.ExecuteNonQuery();
if (rowsAffected > 0)
{
// 4. 存储登录信息
Statics.LoginId = UsernameCBOX.USERNAME.Text;
Statics.LoginPw = PasswordCBOX.PASSWORD.Password;
Hide();
}
else
{
ShowLoginError("User registration failed. Please try again.");
}
}
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
}
}

private void ShowLoginError(string errorMessage)
{
MessageBox.Show(errorMessage);
}
May I ask how you resolved the issue of flashback?
 
Banned
Banned
Joined
Jan 25, 2023
Messages
125
Reaction score
36
C#:
using Black_Desert_Legends.Libs;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Windows;
using System.Windows.Controls;

namespace Black_Desert_Legends.Overlays
{
    /// <summary>
    /// Interaction logic for LoginForm.xaml
    /// </summary>
    public partial class LoginForm : UserControl
    {
        public LoginForm()
        {
            InitializeComponent();
        }

        public void Show()
        {
            AnimHandler.FadeIn(this, 300);
            HideLoginError();
        }

        public void Hide()
        {
            AnimHandler.FadeOut(this, 300);
        }

        private async void BtnLogin_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (!string.IsNullOrEmpty(UsernameCBOX.USERNAME.Text) && !string.IsNullOrEmpty(PasswordCBOX.PASSWORD.Password))
                {
                    string username = UsernameCBOX.USERNAME.Text;
                    string password = PasswordCBOX.PASSWORD.Password;

                    // 发送POST请求给API
                    HttpClient client = new HttpClient();
                    var values = new Dictionary<string, string>
            {
                { "username", username },
                { "password", password }
            };
                    var content = new FormUrlEncodedContent(values);
                    var response = await client.PostAsync("https://example.com/api/login", content);
                    var responseString = await response.Content.ReadAsStringAsync();

                    // 解析API返回的JSON数据
                    JObject responseJson = JObject.Parse(responseString);
                    bool success = (bool)responseJson["success"];
                    string message = (string)responseJson["message"];

                    if (success)
                    {
                        Statics.LoginId = username;
                        Statics.LoginPw = password;

                        Statics.mainWindow._UserTab.LogIn(Statics.LoginId);

                        Hide();
                    }
                    else
                    {
                        if (message == "Account does not exist") // 如果账号不存在,则自动注册
                        {
                            // 发送POST请求给API进行注册
                            var registerValues = new Dictionary<string, string>
                    {
                        { "username", username },
                        { "password", password }
                    };
                            var registerContent = new FormUrlEncodedContent(registerValues);
                            var registerResponse = await client.PostAsync("https://example.com/api/register", registerContent);
                            var registerResponseString = await registerResponse.Content.ReadAsStringAsync();

                            // 解析注册API返回的JSON数据
                            JObject registerResponseJson = JObject.Parse(registerResponseString);
                            bool registerSuccess = (bool)registerResponseJson["success"];
                            string registerMessage = (string)registerResponseJson["message"];

                            if (registerSuccess)
                            {
                                Statics.LoginId = username;
                                Statics.LoginPw = password;

                                Statics.mainWindow._UserTab.LogIn(Statics.LoginId);

                                Hide();
                            }
                            else
                            {
                                ShowLoginError(registerMessage);
                            }
                        }
                        else
                        {
                            ShowLoginError(message);
                        }
                    }
                }
                else
                {
                    ShowLoginError("ID and password are required.");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void ShowLoginError(string message)
        {
            SPError.Visibility = Visibility.Visible;
            ErrorTextBlock.Text = message;
        }

        private void HideLoginError()
        {
            SPError.Visibility = Visibility.Hidden;
        }

        private void BtnCancelLogin_Click(object sender, RoutedEventArgs e)
        {
            AnimHandler.FadeOut(this, 500);

            UsernameCBOX.USERNAME.Text = "请输入账号";
            PasswordCBOX.PASSWORD.Password = "请输入密码";
        }
    }
}
 
Last edited:
Initiate Mage
Joined
Jul 20, 2014
Messages
4
Reaction score
0
View attachment 235385

This release is a launcher for the Play BD Legends private server. I admit this launcher is the most beautiful I've seen in all this time.

It is not just any launcher, it has an auto updater, checking if the server is online or not, login in the launcher itself where it checks if the player has a registered account or not, website news, slides with redirection links.

The launcher itself is very simple and normal code, however it pulls JSON files to perform some tasks, I think this can be changed easily.

Pictures

Files

JSON FILES ARE ATTACHED TO THE THREAD

Who made this launcher: Norea
Can you provide a tutorial? thanks
 
Newbie Spellweaver
Joined
Jan 16, 2015
Messages
5
Reaction score
9
Why can't I download!
In Settings.settings & Settings.Designer.cs the UrlGameFolder must be the link where all your update files are, like " "

in ApiHandler.cs be sure to put the link where the json is:
C#:
        public static async Task<string> GETGameFilesListJSONAsync()
        {
            string URL = "https://website.com/api/GetGameFile.json";
            try
            {
                using (var client = new HttpClient())
                {
                    var response = await client.GetAsync(URL);
                    return await response.Content.ReadAsStringAsync();
                }
            }
            catch
            {
                return string.Empty;
            }
        }

Api file GetGameFile.json is where it takes the updates and downloads them.
So when you make the list specify the link where the files should be (in this case " /")

GetGameFile.json example:
JSON:
[
  {
    "name": "config.exe",
    "url": "https://website.com/download/client/file.txt",
    "size": 123,
    "last_modified": 1634458708,
    "hash": ""
  }
]

PS: from the lister i made be sure to select option 2 to create GetGameFile,
i made GetGameUpdates too in it in the beginning cause i didn't look that GetGameUpdates.json does nothing and is not used in the launcher.
 
Last edited:
Newbie Spellweaver
Joined
Oct 15, 2020
Messages
5
Reaction score
0
Hello, do you think it is easy to adapt to other games? I would like to do it for L2
 
Back
Top