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); } } } }