using System;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
using System.Threading;
using Holo.Managers;
using Holo.Virtual.Users;
using Holo.Virtual.Rooms;
using System.Collections;
namespace Holo.Socketservers
{
///
/// Asynchronous socket server for the MUS connections.
///
public static class musSocketServer
{
private static Socket socketHandler;
private static int _Port;
private static string _musHost;
private static HashSet _activeMusConnections;
private static Hashtable connections = new Hashtable(2);
private static IPAddress[] addresslist;
internal static bool Init(int bindPort, string musHost)
{
_Port = bindPort;
_musHost = musHost;
addresslist = Dns.GetHostAddresses(_musHost);
_activeMusConnections = new HashSet();
socketHandler = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
socketHandler.Bind(new IPEndPoint(IPAddress.Any, bindPort));
socketHandler.Listen(25);
socketHandler.BeginAccept(new AsyncCallback(connectionRequest), socketHandler);
foreach (IPAddress theaddress in addresslist)
{
Out.WriteLine("Conexiones MUS escuchadas desde el puerto " + bindPort + " y IP " + theaddress.ToString());
}
return true;
}
catch
{
Out.WriteError("El puerto " + bindPort + " es inválido o esta en uso.");
return false;
}
}
internal static void freeMusConnection(int connectionID)
{
if (_activeMusConnections.Contains(connectionID))
{
_activeMusConnections.Remove(connectionID);
}
}
private static void connectionRequest(IAsyncResult iAr)
{
try
{
int connectionID = 0;
for (int i = 1; i < 999999; i++)
{
if (_activeMusConnections.Contains(i) == false)
{
connectionID = i;
break;
}
}
if (connectionID > 0)
{
Socket newSocket = ((Socket)iAr.AsyncState).EndAccept(iAr);
string SocketIP = newSocket.RemoteEndPoint.ToString().Split(':')[0];
foreach (IPAddress theaddress in addresslist)
{
if (SocketIP != theaddress.ToString())
{
Out.WriteError("Conexión MUS inválida (" + SocketIP + ")");
newSocket.Shutdown(SocketShutdown.Both);
newSocket.Close();
Socketservers.musSocketServer.freeMusConnection(connectionID);
}
else
{
musConnection newConnection = new musConnection(newSocket);
socketHandler.BeginAccept(new AsyncCallback(connectionRequest), socketHandler);
}
}
}
}
catch { }
socketHandler.BeginAccept(new AsyncCallback(connectionRequest), socketHandler);
}
private class musConnection
{
private Socket Connector;
private byte[] dataBuffer = new byte[10001];
internal musConnection(Socket Connector)
{
this.Connector = Connector;
Connector.BeginReceive(dataBuffer, 0, dataBuffer.Length, SocketFlags.None, new AsyncCallback(dataArrival), null);
}
private void dataArrival(IAsyncResult iAr)
{
try
{
int bytesReceived = new int();
try
{
bytesReceived = Connector.EndReceive(iAr);
}
catch { return; }
string Data = System.Text.Encoding.Default.GetString(dataBuffer, 0, bytesReceived);
string musHeader = Data.ToString().Substring(0, 4);
string[] musData = Data.ToString().Substring(4).Split(Convert.ToChar(2));
#region MUS trigger commands
switch (musHeader)
{
case "HKTM": // Housekeeping - textmessage [BK] :: "HKTM123This is a test message to user with ID 123"
{
int userID = int.Parse(musData[0]);
string Message = musData[1];
userManager.getUser(userID).sendAlert(Message);
break;
}
case "HKMW": // Housekeeping - alert user [mod warn] :: "HKMW123This is a test mod warn to user with ID 123"
{
int userID = int.Parse(musData[0]);
string Message = musData[1];
userManager.getUser(userID).sendModAlert(Message);
break;
}
case "HKUK": // Housekeeping - kick user from room [mod warn] :: "HKUK123This is a test kick from room + modwarn for user with ID 123"
{
int userID = int.Parse(musData[0]);
string Message = musData[1];
virtualUser User = userManager.getUser(userID);
if (User.Room != null)
User.Room.removeUser(User.roomUser.roomUID, true, Message);
break;
}
case "HKAR": // Housekeeping - alert certain rank with BK message, contains flag to include users with higher rank :: "HKAR11This is a test message for all users with rank 1 and higher, so kindof a Hotel alert :D"
{
byte Rank = byte.Parse(musData[0]);
bool includeHigher = (musData[1] == "1");
string Message = musData[2];
userManager.sendToRank(Rank, includeHigher, "BK" + Message + Convert.ToChar(2));
break;
}
case "HKSB": // Housekeeping - ban user & kick from room :: "HKSB123This is a test ban for user with ID 123"
{
int userID = int.Parse(musData[0]);
string Message = musData[1];
virtualUser User = userManager.getUser(userID);
User.sendData("@c" + Message);
User.Disconnect(1000);
break;
}
case "HKRC": // Housekeeping - rehash catalogue :: "HKRC"
{
Thread Refresher;
ThreadStart tStarter = new ThreadStart(refresh_cat);
Refresher = new Thread(tStarter);
Refresher.Priority = ThreadPriority.BelowNormal;
Refresher.Start();
break;
}
case "HKRS": // Housekeeping - refresh configuration :: "HKRS"
{
Thread Refresher;
ThreadStart tStarter = new ThreadStart(refresh_config);
Refresher = new Thread(tStarter);
Refresher.Priority = ThreadPriority.BelowNormal;
Refresher.Start();
Out.WriteAlert("Configuración actualizada con éxito.");
break;
}
case "HKRE": // Housekeeping - refresh Recycler :: "HKRS"
{
Thread Refresher;
ThreadStart tStarter = new ThreadStart(refresh_eco);
Refresher = new Thread(tStarter);
Refresher.Priority = ThreadPriority.BelowNormal;
Refresher.Start();
Out.WriteAlert("Furnis del Ecotron actualizados con éxito.");
break;
}
case "HKRF": // Housekeeping - refresh Filtro :: "HKRS"
{
Thread Refresher;
ThreadStart tStarter = new ThreadStart(refresh_filter);
Refresher = new Thread(tStarter);
Refresher.Priority = ThreadPriority.BelowNormal;
Refresher.Start();
Out.WriteAlert("Filtro de palabras actualizado con éxito.");
break;
}
case "HKMS": // Housekeeping - Emitir mensaje de Apagado.
{
int Minutes = int.Parse(musData[0]);
userManager.sendData("Dc" + Encoding.encodeVL64(Minutes));
break;
}
case "UPRA": // User profile - reload figure, sex and mission (poof!)
{
int userID = int.Parse(musData[0]);
userManager.getUser(userID).refreshAppearance(true, true, true);
break;
}
case "UPRC": // User profile - reload credits
{
int userID = int.Parse(musData[0]);
userManager.getUser(userID).refreshValueables(true, false, 0);
break;
}
case "UPRP": // User profile - reload pixels
{
int userID = int.Parse(musData[0]);
userManager.getUser(userID).refreshValueables(false, true, 0);
break;
}
case "UPRS": // User profile - reload subscription (and badges)
{
int userID = int.Parse(musData[0]);
virtualUser User = userManager.getUser(userID);
User.refreshClub();
User.refreshBadges();
break;
}
case "UPRH":// User profile - reload hand
{
int userID = int.Parse(musData[0]);
userManager.getUser(userID).refreshHand("new");
break;
}
case "UPDU":// User profile - disconnect User
{
int userID = int.Parse(musData[0]);
virtualUser User = ((virtualUser)userManager._Users[userID]);
User.Disconnect(1000);
break;
}
}
#endregion
}
catch { }
}
private void refresh_cat()
{
catalogueManager.Init(true);
}
private void refresh_strings()
{
stringManager.Init("es", true);
}
private void refresh_config()
{
Config.Init(true);
}
private void refresh_filter()
{
stringManager.initFilter(true);
}
private void refresh_fuse()
{
rankManager.Init(true);
}
private void refresh_eco()
{
recyclerManager.Init(true);
}
}
}
}