using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Text;
namespace HabboTunel
{
class Program
{
// BOOT
static void Main()
{
Console.Title = "Habbo Tunel by Timo, Edited by: Privilege & Jairo34";
Console.WriteLine("This server has been coded by Timo");
Console.WriteLine("Edited by: Privilege, Jairo34");
Console.WriteLine("\n\n");
TcpListener serv = new TcpListener(IPAddress.Any, 8888);
serv.Start();
Console.WriteLine("[SOCKET] Server has been listened!");
while (true)
{
if (serv.Pending())
{
TcpClient cl = serv.AcceptTcpClient();
//Los dos Trheaders tienen que tener acceso a los mismos Strings, todos los sockets tendran que tener su propio string de serverData + clientData
/*
* -- TODO: --
*
* serverData + clientData should be changeable
* and readable on both Threads!
* The both threaders must have access to the same strings
* every sockets must have it's own string of ServerData + clientData
*
* -- PARA-HACER: --
*
* serverData + clientData deben ser cambiados
* y legibles en los 2 Threads!
* Los dos Trheaders tienen que tener acceso a los mismos Strings
* todos los sockets tendran que tener su propio string de serverData + clientData
*
*/
String serverData = "@" + Crypto.Encoding.encodeB64("@@" + cl.Client.RemoteEndPoint.ToString().Split(new char[] { ':' })[0]) + "@@" + cl.Client.RemoteEndPoint.ToString().Split(new char[] { ':' })[0];
String clientData = "";
Console.WriteLine("[SOCKET][REQUEST]" + " Socket for " + cl.Client.RemoteEndPoint.ToString().Split(new char[] { ':' })[0] + " has been listened!");
Thread th = new Thread(worker_server);
th.Start();
Thread th2 = new Thread(new ParameterizedThreadStart(worker_client));
th2.Start(cl);
}
else
Thread.Sleep(250);
}
}
// SERVER
#region Server worker
static void worker_server()
{
try
{
IPAddress ip = IPAddress.Parse("78.46.64.208");
IPEndPoint ep = new IPEndPoint(ip, 30000);
TcpClient conn = new TcpClient();
conn.Connect(ep);
while (conn.Connected)
{
// RECEIVE
if (conn.Available > 0)
{
byte[] buff = new byte[conn.Available];
conn.GetStream().Read(buff, 0, conn.Available);
conn.GetStream().Flush();
String thisData = Encoding.ASCII.GetString(buff);
if (thisData != "") { clientData = clientData + thisData; }
}
// RECEIVE
// SEND
if (serverData != "" && clientData == "")
{
String sendData = serverData;
serverData = "";
byte[] buff = new byte[1024];
buff = Encoding.ASCII.GetBytes(sendData);
conn.GetStream().Write(buff, 0, buff.Length);
Console.WriteLine("[SOCKET][SERVER] " + sendData.Replace(Convert.ToString(Convert.ToChar(0)), "{0}").Replace(Convert.ToString(Convert.ToChar(1)), "{1}").Replace(Convert.ToString(Convert.ToChar(2)), "{2}"));
}
// SEND
// SLEEP
if (serverData == "" && clientData == "" && conn.Available == 0)
Thread.Sleep(250);
// SLEEP
}
conn.Close();
}
catch
{ }
}
#endregion
//SERVER
// CLIENT
#region Client worker
static void worker_client(object param)
{
try
{
TcpClient cl = (TcpClient)param;
while (cl.Connected)
{
// RECEIVE
if (cl.Available > 0)
{
byte[] buff = new byte[cl.Available];
cl.GetStream().Read(buff, 0, cl.Available);
cl.GetStream().Flush();
String thisData = Encoding.ASCII.GetString(buff);
if (thisData != "") { serverData = serverData + thisData; }
}
// RECEIVE
// SEND
if (clientData != "")
{
String sendData = clientData;
clientData = "";
byte[] buff = new byte[1024];
buff = Encoding.ASCII.GetBytes(sendData);
cl.GetStream().Write(buff, 0, buff.Length);
Console.WriteLine("[SOCKET][CLIENT] " + sendData.Replace(Convert.ToString(Convert.ToChar(0)), "{0}").Replace(Convert.ToString(Convert.ToChar(1)), "{1}").Replace(Convert.ToString(Convert.ToChar(2)), "{2}"));
}
// SEND
// SLEEP
if (serverData == "" && clientData == "" && cl.Available == 0)
Thread.Sleep(250);
// SLEEP
}
cl.Close();
}
catch { }
}
#endregion
// CLIENT
}
}
// CRYPTO -- Big thanks to Jeax
#region Encryption
namespace Crypto
{
public static class Encoding
{
#region Base64
public static string encodeB64(int value, int length)
{
string stack = "";
for (int x = 1; x <= length; x++)
{
int offset = 6 * (length - x);
byte val = (byte)(64 + (value >> offset & 0x3f));
stack += (char)val;
}
return stack;
}
public static string encodeB64(string Val)
{
int value = Val.Length;
int length = 2;
string stack = "";
for (int x = 1; x <= length; x++)
{
int offset = 6 * (length - x);
byte val = (byte)(64 + (value >> offset & 0x3f));
stack += (char)val;
}
return stack;
}
public static int decodeB64(string Val)
{
char[] val = Val.ToCharArray();
int intTot = 0;
int y = 0;
for (int x = (val.Length - 1); x >= 0; x--)
{
int intTmp = (int)(byte)((val[x] - 64));
if (y > 0)
{
intTmp = intTmp * (int)(Math.Pow(64, y));
}
intTot += intTmp;
y++;
}
return intTot;
}
#endregion
#region VL64
public static string encodeVL64(int i)
{
byte[] wf = new byte[6];
int pos = 0;
int startPos = pos;
int bytes = 1;
int negativeMask = i >= 0 ? 0 : 4;
i = Math.Abs(i);
wf[pos++] = (byte)(64 + (i & 3));
for (i >>= 2; i != 0; i >>= 6)
{
bytes++;
wf[pos++] = (byte)(64 + (i & 0x3f));
}
wf[startPos] = (byte)(wf[startPos] | bytes << 3 | negativeMask);
System.Text.ASCIIEncoding encoder = new ASCIIEncoding();
string tmp = encoder.GetString(wf);
return tmp.Replace("\0", "");
}
public static int decodeVL64(string data)
{
return decodeVL64(data.ToCharArray());
}
public static int decodeVL64(char[] raw)
{
try
{
int pos = 0;
int v = 0;
bool negative = (raw[pos] & 4) == 4;
int totalBytes = raw[pos] >> 3 & 7;
v = raw[pos] & 3;
pos++;
int shiftAmount = 2;
for (int b = 1; b < totalBytes; b++)
{
v |= (raw[pos] & 0x3f) << shiftAmount;
shiftAmount = 2 + 6 * b;
pos++;
}
if (negative)
v *= -1;
return v;
}
catch
{
return 0;
}
}
#endregion
}
}
#endregion
// CRYPTO -- Big thanks to Jeax