summaryrefslogblamecommitdiffstats
path: root/src/Server.h
blob: a6b7297e8373ca4b0412bef67ccc595eded927fe (plain) (tree)
1
2
3
4
5
6
7
8
9
10









                                                                   
 
                                    
                                   











                                     
                                     



                            




 
       

                    
               
                             


                                                     




                    



 
                              
                                         

                        

                             
                                                  
 





                                                                           
                                       

                                                                             


                                                            
                    
 
                         
 
                                                                
        
                                                                                        
                                                                                             
        
                                                                         
                                                                                         
 
                                                                          

                                                     
                            
 
                                                                


                                                                                                                                
 
                                                                                       
        

                                                                                                         
        

                                                                               
        
                                                                                                                                                   
        
                                                                                                            
        
                                                                                      

                                                                
                                                                                                                  

                                                     
                                                                                                                         
                                                        
 
                                                                              
                                                                            
        
                                                                     
                                                                              
        
                                                                                    

                                                                            








                                                                                                                                  



                                                                      
                                                                                                                                                                   












                                                                       
               








                                                                       
                                                                                                 














                                                    

                                               
        

                                         
        


                                                                                                                                                         
        
                                                                                   



                                                                                                                



                                                                                                     
                                                                      

                           
        
                                                                                        
                                    


                                                            


                                 
                              
                              
                         
                           
        


                                 
                                                           

                           



                                                                                









                                                                                                                          
 
                      
 
                                                                                
                               
        
                              
        
                                                                                              
                                     
 

                                                                       
                  



 

// cServer.h

// Interfaces to the cServer object representing the network server





#pragma once

#include "OSSupport/SocketThreads.h"
#include "OSSupport/ListenThread.h"

#include "RCONServer.h"

#ifdef _MSC_VER
	#pragma warning(push)
	#pragma warning(disable:4127)
	#pragma warning(disable:4244)
	#pragma warning(disable:4231)
	#pragma warning(disable:4189)
	#pragma warning(disable:4702)
#endif

#include "PolarSSL++/RsaPrivateKey.h"

#ifdef _MSC_VER
	#pragma warning(pop)
#endif





// fwd:
class cPlayer;
class cClientHandle;
class cIniFile;
class cCommandOutputCallback;

typedef std::list<cClientHandle *> cClientHandleList;

namespace Json
{
	class Value;
}





class cServer  // tolua_export
	: public cListenThread::cCallback
{        // tolua_export
public:  // tolua_export

	virtual ~cServer() {}
	bool InitServer(cIniFile & a_SettingsIni);

	// tolua_begin
	
	const AString & GetDescription(void) const {return m_Description; }

	// Player counts:
	int  GetMaxPlayers(void) const {return m_MaxPlayers; }
	int  GetNumPlayers(void) const;
	void SetMaxPlayers(int a_MaxPlayers) { m_MaxPlayers = a_MaxPlayers; }
	
	// Hardcore mode or not:
	bool IsHardcore(void) const {return m_bIsHardcore; }

	// tolua_end

	bool Start(void);

	bool Command(cClientHandle & a_Client, AString & a_Cmd);
	
	/** Executes the console command, sends output through the specified callback */
	void ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallback & a_Output);
	
	/** Lists all available console commands and their helpstrings */
	void PrintHelp(const AStringVector & a_Split, cCommandOutputCallback & a_Output);

	/** Binds the built-in console commands with the plugin manager */
	static void BindBuiltInConsoleCommands(void);
	
	void Shutdown(void);

	void KickUser(int a_ClientID, const AString & a_Reason);
	
	/** Authenticates the specified user, called by cAuthenticator */
	void AuthenticateUser(int a_ClientID, const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties);

	const AString & GetServerID(void) const { return m_ServerID; }  // tolua_export
	
	/** Called by cClientHandle's destructor; stop m_SocketThreads from calling back into a_Client */
	void ClientDestroying(const cClientHandle * a_Client);
	
	/** Notifies m_SocketThreads that client has something to be written */
	void NotifyClientWrite(const cClientHandle * a_Client);
	
	void WriteToClient(const cClientHandle * a_Client, const AString & a_Data);  // Queues outgoing data for the client through m_SocketThreads
	
	void RemoveClient(const cClientHandle * a_Client);  // Removes the clienthandle from m_SocketThreads
	
	/** Don't tick a_Client anymore, it will be ticked from its cPlayer instead */
	void ClientMovedToWorld(const cClientHandle * a_Client);
	
	/** Notifies the server that a player was created; the server uses this to adjust the number of players */
	void PlayerCreated(const cPlayer * a_Player);
	
	/** Notifies the server that a player is being destroyed; the server uses this to adjust the number of players */
	void PlayerDestroying(const cPlayer * a_Player);

	/** Returns base64 encoded favicon data (obtained from favicon.png) */
	const AString & GetFaviconData(void) const { return m_FaviconData; }
	
	cRsaPrivateKey & GetPrivateKey(void) { return m_PrivateKey; }
	const AString & GetPublicKeyDER(void) const { return m_PublicKeyDER; }
	
	/** Returns true if authentication has been turned on in server settings. */
	bool ShouldAuthenticate(void) const { return m_ShouldAuthenticate; }
	
	/** Returns true if offline UUIDs should be used to load data for players whose normal UUIDs cannot be found.
	Loaded from the settings.ini [PlayerData].LoadOfflinePlayerData setting. */
	bool ShouldLoadOfflinePlayerData(void) const { return m_ShouldLoadOfflinePlayerData; }
	
	/** Returns true if old-style playernames should be used to load data for players whose regular datafiles cannot be found.
	This allows a seamless transition from name-based to UUID-based player storage.
	Loaded from the settings.ini [PlayerData].LoadNamedPlayerData setting. */
	bool ShouldLoadNamedPlayerData(void) const { return m_ShouldLoadNamedPlayerData; }
	
private:

	friend class cRoot; // so cRoot can create and destroy cServer
	
	/** When NotifyClientWrite() is called, it is queued for this thread to process (to avoid deadlocks between cSocketThreads, cClientHandle and cChunkMap) */
	class cNotifyWriteThread :
		public cIsThread
	{
		typedef cIsThread super;
		
		cEvent    m_Event;  // Set when m_Clients gets appended
		cServer * m_Server;

		cCriticalSection  m_CS;
		cClientHandleList m_Clients;
		
		virtual void Execute(void);
		
	public:
	
		cNotifyWriteThread(void);
		~cNotifyWriteThread();
	
		bool Start(cServer * a_Server);
		
		void NotifyClientWrite(const cClientHandle * a_Client);
	} ;
	
	/** The server tick thread takes care of the players who aren't yet spawned in a world */
	class cTickThread :
		public cIsThread
	{
		typedef cIsThread super;
		
	public:
		cTickThread(cServer & a_Server);
		
	protected:
		cServer & m_Server;
		
		// cIsThread overrides:
		virtual void Execute(void) override;
	} ;
	
	
	cNotifyWriteThread m_NotifyWriteThread;
	
	cListenThread m_ListenThreadIPv4;
	cListenThread m_ListenThreadIPv6;
	
	cCriticalSection  m_CSClients;        ///< Locks client lists
	cClientHandleList m_Clients;          ///< Clients that are connected to the server and not yet assigned to a cWorld
	cClientHandleList m_ClientsToRemove;  ///< Clients that have just been moved into a world and are to be removed from m_Clients in the next Tick()
	
	mutable cCriticalSection m_CSPlayerCount;      ///< Locks the m_PlayerCount
	int              m_PlayerCount;        ///< Number of players currently playing in the server
	cCriticalSection m_CSPlayerCountDiff;  ///< Locks the m_PlayerCountDiff
	int              m_PlayerCountDiff;    ///< Adjustment to m_PlayerCount to be applied in the Tick thread
	
	cSocketThreads m_SocketThreads;
	
	int m_ClientViewDistance;  // The default view distance for clients; settable in Settings.ini

	bool m_bIsConnected; // true - connected false - not connected

	bool m_bRestarting;
	
	/** The private key used for the assymetric encryption start in the protocols */
	cRsaPrivateKey m_PrivateKey;
	
	/** Public key for m_PrivateKey, ASN1-DER-encoded */
	AString m_PublicKeyDER;
	
	cRCONServer m_RCONServer;
	
	AString m_Description;
	AString m_FaviconData;
	int m_MaxPlayers;
	bool m_bIsHardcore;
	
	cTickThread m_TickThread;
	cEvent m_RestartEvent;
	
	/** The server ID used for client authentication */
	AString m_ServerID;
	
	/** If true, players will be online-authenticated agains Mojang servers.
	This setting is the same as the "online-mode" setting in Vanilla. */
	bool m_ShouldAuthenticate;
	
	/** True if offline UUIDs should be used to load data for players whose normal UUIDs cannot be found.
	This allows transitions from an offline (no-auth) server to an online one.
	Loaded from the settings.ini [PlayerData].LoadOfflinePlayerData setting. */
	bool m_ShouldLoadOfflinePlayerData;
	
	/** True if old-style playernames should be used to load data for players whose regular datafiles cannot be found.
	This allows a seamless transition from name-based to UUID-based player storage.
	Loaded from the settings.ini [PlayerData].LoadNamedPlayerData setting. */
	bool m_ShouldLoadNamedPlayerData;


	cServer(void);

	/** Loads, or generates, if missing, RSA keys for protocol encryption */
	void PrepareKeys(void);
	
	bool Tick(float a_Dt);
	
	/** Ticks the clients in m_Clients, manages the list in respect to removing clients */
	void TickClients(float a_Dt);

	// cListenThread::cCallback overrides:
	virtual void OnConnectionAccepted(cSocket & a_Socket) override;
}; // tolua_export