Just a relatively simple Loginserver. Definetely ot the best and logins takes ~2 secs, but I've written it in about 2-3 hours(with breaks). If you don't know how to use this and how to make this to compile, you shouldn't ever need this.
using System;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using System.Collections.Generic;
using MySql.Data.MySqlClient;
namespace Loginserver
{
public class Server
{
public static string clientVer = "0.9.3.3044";
static IPAddress serverIP = IPAddress.Any;
static int serverPort = 4001;
public static List<string> serverList = new List<string>();
public static Random rnd = new Random();
static void Main(string[] args)
{
Console.Title = "NosTalgie Authserver - C# Rewrite";
Console.WriteLine("-------------------------------------------------------");
Console.WriteLine(" NosTalgie Authserver");
Console.WriteLine(" Version 0.0.1 Alpha - C# Rewrite");
Console.WriteLine(" developed by Ciapa");
Console.WriteLine("-------------------------------------------------------");
Console.Write(" |I| Populating Serverlist...");
//Server Format: "{IP}:{PORT}:{STATUS}:{SERV}.{CHAN} {NAME}
//Channelstatus:
// 1- 3=Recommended
// 4-11=Normal
//12-18=High Traffic
//19++ =Full
serverList.Add("10.100.10.10" + ":" + 1301 + ":12:1.1." + "S1-Ancelloan");
serverList.Add("10.100.10.10" + ":" + 1302 + ":4:1.2." + "S1-Ancelloan");
serverList.Add("10.100.10.10" + ":" + 1303 + ":1:1.3." + "S1-Ancelloan");
serverList.Add("10.100.10.11" + ":" + 1301 + ":12:2.1." + "S2-Fortuna");
serverList.Add("10.100.10.11" + ":" + 1302 + ":4:2.2." + "S2-Fortuna");
serverList.Add("10.100.10.11" + ":" + 1303 + ":1:2.3." + "S2-Fortuna");
Console.WriteLine(" DONE");
TcpListener serverSocket = new TcpListener(serverIP, serverPort);
TcpClient clientSocket = default(TcpClient);
serverSocket.Start();
Console.WriteLine(" |I| " + "Server Started. Listening on {0}:{1}", serverIP.ToString(), serverPort);
while (true)
{
clientSocket = serverSocket.AcceptTcpClient();
handleClinet client = new handleClinet();
client.startClient(clientSocket);
}
}
}
public class handleClinet
{
TcpClient clientSocket;
public void startClient(TcpClient inClientSocket)
{
this.clientSocket = inClientSocket;
Thread ctThread = new Thread(doLogin);
ctThread.Start();
}
private void doLogin()
{
byte[] bytesFrom = new byte[65536];
string[] cdata = null;
Byte[] sendBytes = null;
string serverResponse = null;
string servers = "";
foreach (string s in Server.serverList)
{
servers = servers + s + " ";
}
try
{
NetworkStream networkStream = clientSocket.GetStream();
networkStream.Read(bytesFrom, 0, bytesFrom.Length);
cdata = LoginDecrypt(bytesFrom, bytesFrom.Length).Split(" ".ToCharArray());
if (cdata[0] == "NoS0575")
{
if (cdata[4].Split(Convert.ToChar("\x0B")).Length == 2)
{
if (cdata[4].Split(Convert.ToChar("\x0B"))[1] == Server.clientVer)
{
string uname = cdata[2];
//If you only want to work with the encrypted password
string encpw = cdata[3];
string decpw = LoginPassDecrypt(encpw);
IPEndPoint cipep = (IPEndPoint)clientSocket.Client.RemoteEndPoint;
IPAddress cipa = cipep.Address;
int session = Login(uname, decpw);
if (session != 0)
{
Console.WriteLine(" |>| Successful Login from IP {0} ; User {1}", cipa.ToString(), uname);
//Response Format: "NsTeST {SESSION} {SERVER} {SERVER}...
serverResponse = "NsTeST " + session + " " + servers;
}
else
{
Console.WriteLine(" |>| Failed Login from IP {0} ; User {1}", cipa.ToString(), uname);
serverResponse = "fail Login fehlgeschlagen. Entweder waren die Zugangsdaten nicht korrekt, du bist gebannt oder du bist bereits online!";
}
}
else
{
serverResponse = "fail Fehler: Clientversion stimmt nicht mit der Serverversion ueberein!";
}
}
}
sendBytes = LoginEncrypt(serverResponse);
networkStream.Write(sendBytes, 0, sendBytes.Length);
networkStream.Flush();
Console.WriteLine(" |<| " + serverResponse);
}
catch (Exception ex)
{
Console.WriteLine(" |E| " + ex.ToString());
}
}
private static int Login(string user, string pass)
{
try
{
string dbConString = "datasource=localhost;port=3306;username=root;password=ZENSIERT";
MySqlConnection dbCon = new MySqlConnection(dbConString);
MySqlCommand dbCmd = new MySqlCommand("select * from nostalgie_dev.tbl_accounts where User=@user and Password=@password and IsBlocked=0 and IsOnline=0;", dbCon);
dbCmd.Parameters.AddWithValue("@user", user);
dbCmd.Parameters.AddWithValue("@password", pass);
MySqlDataReader dbReader;
dbCon.Open();
dbReader = dbCmd.ExecuteReader();
int i = 0;
int id = 0;
int session = Server.rnd.Next(10000, 99999);
while (dbReader.Read())
{
i++;
id = dbReader.GetInt32("AccountID");
}
dbCon.Close();
if (i == 1)
{
MySqlConnection dbConx = new MySqlConnection(dbConString);
MySqlCommand dbCmdx = new MySqlCommand("UPDATE nostalgie_dev.tbl_accounts SET LastSession=@session WHERE AccountID=@id;", dbConx);
dbCmdx.Parameters.AddWithValue("@session", session);
dbCmdx.Parameters.AddWithValue("@id", id);
MySqlDataReader dbReaderx;
dbConx.Open();
dbReaderx = dbCmdx.ExecuteReader();
while (dbReaderx.Read())
{
}
dbConx.Close();
return session;
}
return 0;
}
catch (Exception ex)
{
return 0;
}
}
private static string LoginDecrypt(byte[] tmp, int size)
{
for (int i = 0; i < size; i++) tmp[i] = (byte)(tmp[i] - 0xF ^ 0xC3);
return Encoding.ASCII.GetString(tmp).Substring(0, size);
}
private static byte[] LoginEncrypt(string str)
{
str += " ";
byte[] tmp = new byte[str.Length + 1];
tmp = Encoding.ASCII.GetBytes(str);
for (int i = 0; i < str.Length; i++) tmp[i] = Convert.ToByte(str[i] + 15);
tmp[tmp.Length - 1] = 25;
return tmp;
}
private static string LoginPassDecrypt(string tmp)
{
bool equal = tmp.Length % 2 == 0 ? true : false;
string str = equal == true ? tmp.Remove(0, 3) : tmp.Remove(0, 4);
string dec_pass = string.Empty;
for (int i = 0; i < str.Length; i += 2) dec_pass += str[i];
if (dec_pass.Length % 2 != 0)
{
str = dec_pass = string.Empty;
str = tmp.Remove(0, 2);
for (int i = 0; i < str.Length; i += 2) dec_pass += str[i];
}
StringBuilder temp = new StringBuilder();
for (int i = 0; i < dec_pass.Length; i += 2) temp.Append(Convert.ToChar(Convert.ToUInt32(dec_pass.Substring(i, 2), 16)));
dec_pass = temp.ToString();
return dec_pass;
}
}
}
Feel free to post fixes and improvements.
Don't blame me if it looks shitty coded, it's recoded from my C++ Servers, which look much prettier and work like 10 times faster. The "big daddy" has much more features, like Maintenance mode, dynamic channel load indicator and dynamic channel list(from config, checks which servers and channels are online). It was a bet with a friend of mine that I can't do this in less than 3 hours.
Don't forget to leave a thanks if you find this useful
You can find more information about the real server on this page soon™: <-It's a work in progress, People can join it once the server is finished
this always worked ernilos just want to explain how it's done in reality on official server.^^ it's not very if session is random or incremental but if you want to stay near the official server session is incremental
Please.. Why !? A static list is just stupid.. World has to connect to Authentication giving own data that will be added to the list.
Are you an idiot, or are you just behaving like one? This is a simple REWRITE and only consists of the login server. As I already said, the big daddy has dynamic loading. And, this is for every Server, like a simple replacement. Tell me how you would teach for example waat or xenocore or SoE(without source edits) to talk to Auth about Server Status and so on.
If you think you can, well, do it! Read the first post.
Then do it. Gimme a fully working project. You have two hours, from now on!
Give up, troll... no one likes you. And now back in your cage!
Did it in previous live, happy that you didn't look for it.. Nobody likes me (really?) but you are using my crypto version and tools.. Is funny to read what you are writing without know who i am. Funny to have another idiot on this community.